Softlemon API Documentation
  • Merchant API
  • Partner API
  • Guides
API basics
    API ConventionsEnvironmentsError HandlingRate LimitsSCA and PSD2SupportChangelog
Integration flows
    Accept a Card PaymentAuthorize Now, Capture LaterRefund a PaymentCharge a Returning CustomerAccept an Alternative PaymentPaysafecard via Skrill: Customer JourneySet Up WebhooksIntegrate as a Partner
Reference
    Merchant Transaction WebhooksTransaction StatusesDuplicate Payment Protection
Integration flows

Charge a Returning Customer

After a customer's first successful card payment, the gateway stores the card as a reusable payment instrument in its vault. Later payments can then reference the stored card with a vault token instead of collecting the full card details again. The customer only re-enters the CVV.

Step 1: Take the first payment and store the token

Process the first payment with full card details, exactly as described in Accept a card payment. When the payment succeeds and the acquirer supports vaulting, the response includes a payment_instrument object with the stored card and its vault_token:

JSON
{ "success": true, "message": "Transaction initiated", "code": "", "data": { "transaction": { "id": 2, "status": "auth", "payment_instrument": { "payment_instrument_id": "pi_01k24d5re8xh1v0c9jc0m8w3ns", "vault_token": "8ac7a4a29852f6f101985300a1b41c2f", "type": "card", "status": "active", "card_brand": "visa", "card_last_four": "1111", "card_expiry_month": 12, "card_expiry_year": 2030 } } } }

Persist the vault_token server-side against your customer record. Treat it as a sensitive value: never expose it in browsers or logs. The card_brand and card_last_four fields are safe to show the customer when offering the stored card at checkout.

Step 2: Charge the stored card

For a later payment, call POST /api/v1/transactions with vault_token in place of the card number and expiry. Only the CVV is still needed:

curl https://api.sandbox.softlemons.com/api/v1/transactions \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer {YOUR_API_KEY}' \ --data '{ "transaction_type": "sale", "amount": 24, "currency": "EUR", "reference": "ORDER-912401", "vault_token": "8ac7a4a29852f6f101985300a1b41c2f", "card": { "cvv": "123" } }'

Notes on the request:

  • vault_token and full card details are alternatives. When the token is present, card.number, card.exp_month and card.exp_year are not required.
  • vault_token is mutually exclusive with wallet payments.
  • Vault tokens are scoped to the merchant that stored the card. A token from another merchant account fails validation exactly like an unknown token.
  • Use a fresh reference for every new payment. Charging the same customer again is a new payment, not a retry. See the duplicate protection guide.

The response, statuses and webhook events are identical to a normal card payment. The same capture, void and refund flows apply afterwards.

Manage stored cards

List the cards stored for your account with GET /api/v1/payment-instruments. The endpoint is paginated and accepts a status filter. Partner API keys add merchant_id for a linked merchant:

curl 'https://api.sandbox.softlemons.com/api/v1/payment-instruments?status=active' \ --header 'Authorization: Bearer {YOUR_API_KEY}'

When a customer removes a card or asks you to delete their data, revoke the instrument by its payment_instrument_id:

curl https://api.sandbox.softlemons.com/api/v1/payment-instruments/pi_01k24d5re8xh1v0c9jc0m8w3ns \ --request DELETE \ --header 'Authorization: Bearer {YOUR_API_KEY}'

An instrument is active, expired or revoked. Only active instruments can be charged: a revoked token fails POST /api/v1/transactions with HTTP 400 and code ERR_INVALID_CARD_TOKEN. Revocation is idempotent and does not touch past transactions. If the customer pays with the same card again later, the instrument reactivates with the same token.

3D Secure on repeat payments

Whether a repeat payment needs a fresh 3DS verification depends on your acquirer's rules for merchant-initiated and recurring payments. When it is required, run the same POST /api/v1/3ds/verify step as a first payment and pass card_verification_data.id on the transaction.

Last modified on September 7, 2026
Refund a PaymentAccept an Alternative Payment
On this page
  • Step 1: Take the first payment and store the token
  • Step 2: Charge the stored card
  • Manage stored cards
  • 3D Secure on repeat payments
JSON