2

My code creates and loads the Stripe Checkout where the customer enters name and card details and is returned to a php script where the token is received and used to create a Stripe customer and then send a purchase request to charge their card.

How would I best add a subscription using the same card and the omnipay library where possible? Do I use the token or grab the source id from the purchase object and use that, and create a subscription after the purchase?

Inside a class, the call to createSubscription in the code below gives the error "This customer has no attached payment source".

public function createSubscription($token,$customer_id,$plan,$source_id)
{
        try {
            $response = $this->gateway->createSubscription(
                                array(
                                    'customerReference' => $customer_id,
                                    'plan'              => $plan,
                                    'source'            => $token
                                )
            )->send();
            if ($response->isSuccessful()) {
                $data = $response->getData();
return $data;
            }
        } catch (Exception $e) {
            $message = "Error creating Stripe subscription: " . $e->getMessage();
            return;
        }
    }
Nick W
  • 877
  • 2
  • 15
  • 30
  • Stripe subscriptions will always charge the default card (default_source) on a customer, so if you've already added a card there is no need to pass 'source' What are you passing to 'source' here? A token obtained from Stripe.js/Checkout (for testing: tok_visa)? – duck Jul 18 '17 at 22:45
  • I tried passing the token received from Stripe after the customer completes their 'Checkout'. Not sure whether 'source' here can be a token or whether it has to be either a source id or card object. I will try adding a subscription after charging the card, but not sure if the source will only be suitable for a one-time charge. – Nick W Jul 19 '17 at 06:49
  • Couldn't get it to work after the purchase with either the source id or the token, I got 'invalid_request_error - This customer has no attached payment source'. I'll try again using the create customer request. – Nick W Jul 19 '17 at 09:47

2 Answers2

0

I've succeeded by creating the customer with card details attached using the token, then creating a subscription using the 'plan' and 'customerReference' parameters, and to finally charging the card using the customerReference (isSuccessful check and error checking omitted for clarity):

 $response = $gateway->createCustomer(array(
     'description'       => 'Test Customer',
     'email'             => $_POST['stripeEmail'],
     'source'  => $token
 ))->send();

 $response = $gateway->createSubscription(array(
     "customerReference" => $customer_id,
     'plan' => 'plan_name',
 ))->send();

$transaction = $gateway->purchase(array(
                  'amount'   => '5.00',
                  'currency' => 'gbp',
                  'receipt_email' => 'test@test.com',
                  "description" => 'Test Order',
                  'customerReference' => $customer_id,
));
Nick W
  • 877
  • 2
  • 15
  • 30
0

OmniPay is supposed to do:

#1 Abstract so-called payment-gateways (like Stripe), and devide gateways into general interfaces or general methods (like purchase(...) method).

#2 By doing #1, help us skip the learning time required for each gateway (i.e. Payment-API), so that we just need to learn OmniPay.

#3 Also #1 allows our site(s) to support multiple gateways, without much re-writting, and without wasting time learning each-and-every gateway.

But OmniPay simply isn't doing #1 of above for Stripe, for example, OmniPay's createCustomer(...) and createSubscription(...) are not even part of said general interfaces, and you need to type-cast the gateway, to be even able to see them in auto-completion.

In other words, because #2 and #3 strongly depend on #1, if you just need Stripe, then OmniPay has absolutely no benefit, and forces you to learn both "official Stripe API" and their "OmniPay Stripe gateway" (which has not much documention even now in 2022, but "official Stripe API" does).

I strongly recommend using Stripe's own Composer package (i.e. stripe-php).

In your case, follow their guide at:
https://stripe.com/docs/billing/subscriptions/fixed-price

Top-Master
  • 7,611
  • 5
  • 39
  • 71