Jump to content

Seb

Administrators
  • Posts

    670
  • Joined

  • Last visited

Everything posted by Seb

  1. Realised we didn't update here. This option has been live for a while
  2. No, we will implement Enhance level SSO once Enhance release SSO.
  3. Two very separate things here On restricting payment methods to countries, I've added an issue for that. On converting a product price, can you explain what you mean. A country doesn't have a product price - that's defined by currency. You can already restrict gateways by currency.
  4. We're going to work on full 'trial' functionality later this month 🙂
  5. Yeah we know we have to build some 'bulk update' features
  6. Honestly, most of our paying customers don't care about the branding and keep it. If this wasn't an optional extra we'd have to increase prices for everyone.
  7. I think what we'll do with the enhance integration in the medium term is just remove the requirement for a domain as it doesn't need it. Our implementation just requires it right now but it won't in future.
  8. 1. What would happen in the case of a product free for the first 3 months then the price changes to $5 per month? We store on the contract product at the time of ordering so it would revert to the price originally stored not the new catalogue price. 2. What happens to existing customers where product prices need to be increased each year? You would have to change them on the individual existing contract products. We can create tooling and endpoints to do that in bulk. 3. Can clients cancel a free product? Yes
  9. I don't think they have checkout flows yet. The only thing we could do is basically get a webhook when a payment arrives -- but then we'd have to try and match it with an account and then associate with invoices / add to credit if it doesn't match, as well as flag payments that we can't match - I think it gets messy and we'd be better to wait for them to have a checkout flow. Other gateways do this great -- like Paystack and Flutterwave. They basically provide let you initiate a payment, then you pay via bank transfer, and then they say the payment is complete.
  10. I just put a very simple proof of concept together for a client to give them endpoints, so am putting this here in case any one wants to use it as a base for something. This is not production-ready code and I've just put it together very quickly as an example. But it would let a client enter their username and password to Upmind and then log them directly in to their service (e.g. cPanel) as long as they only had one service: <?php // Input fields $brandurl = "https://my.brandurl.com"; class upmindAuth { public $api_url; public $origin; public $token; function __construct($origin){ $this->api_url = 'api.upmind.io'; //live api url $this->origin = $origin; // Brand Origin } public function validate($username,$password){ if (!$this->api_token('/oauth/access_token',array('username'=>$username,'password'=>$password,'grant_type'=>'password'))){ return false; } $account = $this->get('/api/accounts'); $this->post('/api/accounts/select',array('account_id'=>$account->data[0]->id)); return $this->get('/api/clients/'.$account->data[0]->pivot->client_id.'?with=custom_fields,tags'); } public function api_token($endpoint,$params){ $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://".$this->api_url."/oauth/access_token", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($params), CURLOPT_HTTPHEADER => array( "accept: application/vnd.pub.v1+json", "cache-control: no-cache", "content-type: application/json", "origin: $this->origin", ), )); $response = curl_exec($curl); $err = curl_error($curl); if ($err) { return array('success'=>false,'error'=>"cURL Error #:" . $err); } else { $actor = json_decode($response); if ($actor->status == 'error') { return false; } if ($actor->second_factor_required){ $this->token = $actor->access_token; $authresponse = $this->post('/oauth/access_token',array('grant_type'=>'twofa','twofa_code'=>$_POST['2fakey'])); if ($authresponse->status == 'error'){ return false; } $this->token = $authresponse->access_token; return true; } $this->token = $actor->access_token; return true; } } public function get($endpoint){ $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://".$this->api_url.$endpoint, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => array( "authorization: Bearer ".$this->token, "cache-control: no-cache", "origin: ".$this->origin, ), )); $response = curl_exec($curl); $err = curl_error($curl); if ($err) { echo "cURL Error #:" . $err; } else { return json_decode($response); } } public function post($endpoint,$params){ $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://".$this->api_url.$endpoint, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => http_build_query($params), CURLOPT_HTTPHEADER => array( "authorization: Bearer ".$this->token, "cache-control: no-cache", "origin: ".$this->origin, ), )); $response = curl_exec($curl); $err = curl_error($curl); if ($err) { echo "cURL Error #:" . $err; } else { return json_decode($response); } } } $upmind = new upmindAuth($brandurl); $userobject = $upmind->validate($_POST['email'],$_POST['password']); if (!$userobject){ $values['error'] = "Login details incorrect"; } else { $contractproducts = $upmind->get('/api/contracts_products?filter[status.code]=contract_active'); if (sizeof($contractproducts->data) !== 1){ die('not just one product'); } $provisionfunctions = $upmind->get('/api/contracts/' . $contractproducts->data[0]->contract_id . '/products/' . $contractproducts->data[0]->id.'/provision_functions'); foreach ($provisionfunctions->data as $f){ if ($f->name == 'getLoginUrl'){ $login = $upmind->post( '/api/contracts/' . $contractproducts->data[0]->contract_id . '/products/' . $contractproducts->data[0]->id.'/provision_requests', array( 'provision_field_values' => array(), 'blueprint_function_id' => $f->id )); foreach ($login->data->action_logs as $l){ if (isset($l->data->redirect_url)){ header("Location: " . $l->data->redirect_url); } } } } } ?> <form method="post"> <input type="text" name="email" placeholder="[email protected]"><br /> <input type="password" name="password" placeholder="password"><br /> <input type="text" name="2fakey" placeholder="2fa (optional)"><br /> <input type="submit">
  11. We've created an issue for BCC and CCing emails. I think it's best if it's an option on the email template, because there are some emails you might not want to be CC'd on, and others we would really want to block (password resets etc). On MailChimp, we'll work on this in the same way we're doing WebHooks, CampaignMonitor and SMS messages, as a notification channel. I can't give an ETA but reworking the notification channels is quite important.
  12. The powered-by branding is an optional extra. Our pricing is very cheap and we don't have a huge marketing budget so the small fee offsets the loss to us of a link.
  13. Our workbench is now published at https://github.com/upmind-automation and we will soon be pushing out existing domain provider code Any third party (including Crazy Domains) will be able to develop their own integrations. We can add to our roadmap if no one else works on it but it's not high on our list. We never give ETAs
  14. An invoice can't be cancelled. That doesn't exist in accounting. It can only be credited. An invoice is an official tax document and if you want to write it off you need a credit note on the other side of the ledger to balance it against. WHMCS is in many areas an example of how invoicing shouldn't be done. Legacy invoices are ones that have come from a previous system. They aren't ones you can pay. We generate new invoices based on the service due dates, billing cycle and recurring amounts. Legacy invoices we couldn't map to periods for reporting/MRR/churn rate calculations etc.
  15. You can see these all through logs -> email history. We put every single email there with delivery status, map it to the template that was sent, and link to the action that triggered it.
  16. Yes, we don't set ETAs because we need to be flexible and change our development cycle and roadmap to adapt to issues we find or important features we need to add. When we are out of beta we will publish a roadmap.
  17. We could probably just show both
  18. It's later this month, not out yet.
  19. A few reasons - it added complexity to signup, we didn't want to get to the stage where people were using other brand names, people were already starting to ask us to change it 🙂 We'll likely bring some options in in future where you can set a custom one with a variety of top levels. (e.g. yourbrand.[generic.com]) With SES we have a limit of 5,000 top level senders (e.g. generic.com) which is why we can't send out from actual brand domains.
  20. What's the reason to do this? Is it for Trustpilot AFS?
  21. This is something we'll handle with product bundles in future. At the moment you can bundle products but there's no provisioning on bundles. We'll add this
  22. This is a function we can build. Good idea
  23. You would be best to use product options or attributes
  24. Provided the gateway is established and has decent technical documentation we can add the integration to our list - what is the gateway?
×
×
  • Create New...