eronn
eronn

Reputation: 1830

Stripe - Pay order error : Cannot charge a customer that has no active card

I am using Stripe's API to pay for orders.

My plan is generally the following:

  1. Creation of the payment form with Stripe Elements

  2. Card authentication (3d secure security SCA) through the use of a PaymentIntent then the creation of a PaymentMethod.

  3. Creation of the Customer object, to which I attach the payment method, and which I define as default

$customer = $this->stripeConnector->updateCustomer($customer->id, [
     'invoice_settings' => [
          'default_payment_method' => $paymentMethod->id,
        ],
   ]);
  1. Creation of the subscription, or of a single payment.

Normally it works fine.

But not for the Order. I create Order Object following the documentation : https://stripe.com/docs/api/orders/create with the orders items and the associated Customer

And I pay it following the following documentation https://stripe.com/docs/api/orders/pay

So, just by passing the Order id (because the customer is already associated to the order).

But I've the following error : Cannot charge a customer that has no active card

Why ? And how can I 'activate' the customer card ?

This is an example of a Customer data that I have :

{
  "id": "cus_JocNLLNhqHuOD6",
  "object": "customer",
  "address": {
    "city": "paris",
    "country": "FR",
    "line1": "5 rue pompidou",
    "line2": null,
    "postal_code": "75000",
    "state": null
  },
  "balance": 0,
  "created": 1625758082,
  "currency": null,
  "default_source": null,
  "delinquent": false,
  "description": null,
  "discount": null,
  "email": "[email protected]",
  "invoice_prefix": "D46F6A15",
  "invoice_settings": {
    "custom_fields": null,
    "default_payment_method": "pm_1JAz8uGgCQgXBLKX2hoxLQHr",
    "footer": null
  },
  "livemode": false,
  "metadata": {
  },
  "name": "admin admin",
  "next_invoice_sequence": 1,
  "phone": null,
  "preferred_locales": [
    "fr"
  ],
  "shipping": null,
  "tax_exempt": "none"
}

And my PaymentMethod response :

{
  "id": "pm_1JAz8uGgCQgXBLKX2hoxLQHr",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": "qsvsf",
    "phone": null
  },
  "card": {
    "brand": "visa",
    "checks": {
      "address_line1_check": null,
      "address_postal_code_check": null,
      "cvc_check": "pass"
    },
    "country": "US",
    "exp_month": 5,
    "exp_year": 2025,
    "fingerprint": "oV7uH07M2JEz7jQm",
    "funding": "credit",
    "generated_from": null,
    "last4": "4242",
    "networks": {
      "available": [
        "visa"
      ],
      "preferred": null
    },
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": null
  },
  "created": 1625758080,
  "customer": "cus_JocNLLNhqHuOD6",
  "livemode": false,
  "metadata": {
  },
  "type": "card"
}

Looking at the doc on the payment of an Order object, I wonder if I should instead use the 'source' option and therefore use a Source object instead of a PaymentMethod. But the problem is, the Source Object is deprecated in favor of the PaymentMethod to favor 3d secure, so I have to use it.

Upvotes: 0

Views: 880

Answers (1)

hmunoz
hmunoz

Reputation: 3311

Orders is a long deprecated Stripe API, so I would recommend moving away from it, to PaymentIntents or one-off Invoices.

Since it is a legacy API, it only works with Cards/Sources and not PaymentMethods.

Right now your integration is attaching a PaymentMethod to your Customer.

Orders doesn't look for your Customer's PaymentMethods but instead it looks under the sources: param on your Customer.

Orders also don't support SCA, so if a payment requires authentication, that would just surface as a decline and not give you the authentication life-cycle functionality that PaymentIntents give you.

That is why it works as you said, when you save a "Source" object under the Customer's source:.

The right approach would be to move away from using deprecated Card/Source objects and the Orders API, and integrate PaymentMethods (which you already have integrated) and PaymentIntents or Invoices or CheckoutSessions.

Upvotes: 2

Related Questions