WooshPay OpenAPI
Product DocumentAPI ReferenceJS SDK ReferenceSaaS Platform Integration
Product DocumentAPI ReferenceJS SDK ReferenceSaaS Platform Integration
Back to WooshPay Website
  1. Save a customer's payment method when they use it for a payment
  • Online payments
    • Quick Start
    • Integration overview
    • Wooshpay JS SDK
    • Wooshpay Checkout
    • Wooshpay Direct API
    • Payment Link
    • Authorize and capture
    • Build subscriptions integration
    • Testing cards
  • After the payment
    • Webhook
    • Check the webhook signatures
    • 校验webhook签名
  • Add more payment methods
    • Supported payment method
    • Cards
    • Wallets
      • Alipay
      • Alipay HK
      • Apple Pay
      • Google Pay
      • Wechat Pay
      • 微信支付
      • Kakao Pay
      • DANA
      • Boost
      • Grabpay
      • Mcash
      • Touch'n Go
      • ShopeePay
      • UnionPay
      • 9Pay
      • OVO
      • GCash
      • TrueMoney
    • Bank redirects
      • Bancontact
      • BPI
      • Trustly
      • EPS
      • Giropay
      • iDEAL
      • Przelewy24
      • FPX
    • Buy Now Pay Later
      • Klarna
    • Bank Debits
      • Sepa Direct Debit
    • Bank Transfer
      • Bank Transfer in Europe
      • Bank Transfer in United Kingdom
      • Bank Transfer in Indonesia
      • Bank Transfer in Nigeria
      • Bank Transfer in South Africa
    • QR Payments
      • QRIS
      • PromptPay
    • Real-time payments
      • PIX
      • PayNow
      • UPI
      • SPEI
    • Mobile Money
      • Mobile Money - Multi-Country Integration Guide
  • More payment scenarios
    • Save a customer's payment method when they use it for a payment
      • Save payment details during payment with Direct API
      • Save payment method during payment with Drop-in
    • Save a customer's payment method without making a payment
      • Save a payment method with Wooshpay Checkout
      • Save a payment method with Drop-in
      • Save a payment method with Direct API
  • SaaS platform integration
    • Shopify Plugin
    • WooCommerce
    • Shoplazza 店匠
    • Shopastro 星盘
    • Shopline Plugin
    • Sage Connection
  • Payouts
    • Overview
    • Cameroon
    • Europe
    • Ghana
    • Kenya
    • Nigeria
    • Rwanda
    • South Africa
    • Tanzania
    • Uganda
    • United Kindom
    • United States of America
    • Monitor Your Payout Results
  • Resources
    • Supported currencies
  1. Save a customer's payment method when they use it for a payment

Save payment details during payment with Direct API

This guide shows how to charge now and store the card for future charges in a single server-side call by creating a PaymentIntent that includes payment_method_data and setup_future_usage.
PCI-DSS scope notice
Posting PAN/CVC directly to your servers places you in SAQ D scope. If you want to minimize PCI burden, use Drop-in or Checkout instead.

1. Prerequisites#

ItemNotes
Secret keyUse server-side only.
Customer IDReuse an existing customer or create one with POST /v1/customers (email recommended).
Return URLA page to receive the user after 3-D Secure (return_url).
WebhooksExpose an HTTPS endpoint. Treat payment_intent.succeeded as the authoritative payment-success signal (and that the card is saved to the customer).

2. Create & confirm a PaymentIntent (pay and save)#

Create a PaymentIntent
request
{
  "amount": 100,
  "currency": "USD",
  "confirm": true,
  "customer": "cus_1760950869144109056",
  "payment_method_data": {
    "type": "card",
    "card": {
      "exp_month": "01",
      "exp_year": "2027",
      "number": "4111111111111111",
      "cvc": "022",
      "name": "XX XXX"
    }
  },
  "setup_future_usage": "on_session",
  "return_url": "https://yourwebsite.com"
}
Outcomes
Frictionless success → status: "succeeded" (no 3DS).
3-D Secure required → status: "requires_action" with a next_action.
Failure → status: "requires_payment_method" (invalid card, insufficient funds, etc.).

3. Complete 3-D Secure (if requires_action)#

If the response is:
{
  "id": "pi_XXXX",
  "status": "requires_action",
  ....
  "next_action": {
    "type": "challenge_redirect",
    "challenge_redirect": {
      "url": "https://jstest.wooshpay.com/v1/3ds/index.html?...",
      "return_url": "https://yourwebsite.com"
    }
  },
  "customer": "cus_1760950869144109056",
  "payment_method": "pm_XXXX",
  .....
}
Do this:
1.
Redirect the customer to next_action.challenge_redirect.url.
2.
They complete the bank challenge and are returned to your return_url.
3.
Do not assume success solely from the redirect. Your source of truth is the webhook in the next section.
Optional: You may poll GET /v1/payment_intents/{id}, but rely on the webhook for final state.

4. Handle webhooks#

Enable and handle at least:
EventPurposeWhat to store
payment_intent.succeededAuthoritative indicator that the payment completed and the card was saved to the customer (because setup_future_usage was set and customer supplied).Persist (customer_id, payment_method_id) for future charges. You can read event.data.object.payment_method.
Example(abridged)
{
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      "id": "pi_XXXX",
      "status": "succeeded",
      ....
      "customer": "cus_XXXXXXXXXX",
      "payment_method": "pm_XXXXXXXXXXXX",
      ....
    }
  }
}

5. Charge the card later#

Create a PaymentIntent
{
  "amount": 2500,
  "currency": "USD",
  "confirm": true,
  "off_session": false,          // true if no user present
  "customer": "cus_1953770230215868416",
  "payment_method": "pm_123123123",
  "return_url": "https://example.com/pay/complete"
}
Key pointValue
customerID from Step 1.
payment_methodSaved card’s ID from webhook or listing API.
off_sessionfalseto attempt and on-session charge(user present now)true to attempt an off-session charge (recurring / unsupervised).
Status guide (server actions)
payment_intent.statusMeaningYour next step
requires_payment_methodCard entry/processing failureShow error; allow new card.
requires_action3-D Secure step-up requiredRedirect to next_action.XXXX.XXXX.
processingBank/network is processingWait for webhook; avoid duplicate submissions.
succeededPaid and card saved to customerPersist mapping; fulfill the order.

6. Testing#

ActionTest card numberNotes
Successful save + charge4111 4111 41111 4111Any future date, any CVC
3-D Secure required4462030000000000Checkout will prompt for 3DS challenge
Use your test secret key and point webhooks to your dev endpoint.

Quick reference#

TaskAPI
Create customerPOST /v1/customers
Pay & save (Direct API)POST /v1/payment_intents (with payment_method_data + setup_future_usage)
Authoritative successpayment_intent.succeeded
Charge laterPOST /v1/payment_intents (with customer + saved payment_method)
Modified at 2025-08-13 09:58:26
Previous
Mobile Money - Multi-Country Integration Guide
Next
Save payment method during payment with Drop-in
Built with