2
votes

I want the 3d-secure modal authorization check with subscription type = trialing.

I am following this link to setup stripe subscription. When I create subscription without 'trial_period_days' the 3d-secure authorization modal pops-up as subscription status becomes 'incomplete'.

But when i pass >trial_period_days and 'payment_behavior' => 'allow_incomplete', modal don't work as subscription status becomes 'active'.

How can i show authorization modal when subscription is trialing? I have seen this link https://stripe.com/docs/payments/3d-secure#manual-three-ds too, but no progress.

Suggest me a way to implement this.

Here is my code:

public function createCustomer($token) {
    \Stripe\Stripe::setApiKey(secretKey);

    $customer = \Stripe\Customer::create([
      'email' => '[email protected]',
      'source' => $token,
    ]);

    return $this->createSubscription($customer, $token);    
}

public function createSubscription($customer, $token) {
    $plan_id = $this->getPlanId();
    $payment_intent = $this->createSetupIntent($customer->id, $token);
    $subscription = \Stripe\Subscription::create([
      'customer' => $customer->id,
      'items' => [
        [
          'plan' => $plan->id, 
        ],
      ],
      'trial_period_days' => 14,
      'expand' => ['latest_invoice.payment_intent'],
      'payment_behavior' => 'allow_incomplete',
    ]);

    return [
       'subscription' => $subscription, 
       'payment_intent' => $payment_intent
    ];
}

public function createSetupIntent($customer_id, $token) {
    $client = new Client();
    $url = "https://api.stripe.com/v1/setup_intents";
    $response = $client->request('POST', $url, [
      'auth' => ['sk_test_key', ''],
      'form_params' => [
        'customer' => $customer_id,
        'payment_method_types' => ["card"],
        'payment_method_options' => [
            "card" => [
              "request_three_d_secure" => "any"
            ]
          ]
      ],
      'timeout' => 10.0
    ]);
    $setup_intent = $response->getBody()->getContents();
    return json_decode($setup_intent, true);
  }

I expect 3d-secure authorization check modal too when i set subscription to trialing.

1
did you found a solution to that? I'm facing the same issue and would be nice to know how to proceed - Leonardo Rick

1 Answers

2
votes

What you are describing is a scenario in Stripe doc

Basically when you create a subscription with trial period, since there is no immediate payment occurs, there will be no 3DS authentication needed.

The authentication is delayed until the trial period end.

To ask the user for authentication so that when the trial end there will be no need for 3DS authentication, when a subscription is created with trial period, The subscription will have a pending_setup_intent attribute

You could use that pending_setup_intent to ask the user to complete the authentication. You don't have to create a setup Intent explicitly. What you can do is to check the status within the subscription.

If subscription is in trialing, check if there is a pending_setup_intent, if so, pass to the pending_setup_intent.client_secret to the frontend where your customer is subscribing to your product, and call Stripe.js handleCardSetup

stripe.handleCardSetup(psi.client_secret)
  .then(siResult => {
     log({siResult});
  }).catch(err => {
     log({siErr: err});
  });

When the card is setup and the trial ends, there will be less likely that the charge will need to go through 3DS authentication again.

You could use Stripe Test Card, 4000002500003155 is good for this testing. You could simulate the trial end by updating the subscription with

trial_end: "now"
off_session: true // This is needed because by default, subscription update is considered on_session

Hope the above helps