Make Token Payments
Process payments using saved tokens for returning customers, subscriptions, and merchant-initiated transactions
Make Token Payments
Once you've created a token, you can use it to process payments without requiring the customer to re-enter their card details. This guide covers all scenarios for making payments with tokens.
Overview
Token payments fall into two categories based on who initiates the payment:
| Scenario | Shopper Interaction | Use Case |
|---|---|---|
| Customer-initiated | Ecommerce or ContractPresent | One-click checkout, reorders |
| Merchant-initiated | ContractPresent | Subscriptions, usage billing, automatic top-ups |
Customer-Initiated Payments
When the customer is present and actively initiating the payment (e.g., clicking "Pay Now" on your checkout), use shopper_interaction: "Ecommerce".
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 15000,
"currency": "KZT",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "CardOnFile",
"shopper_interaction": "Ecommerce",
"return_url": "https://yoursite.com/order/complete",
"description": "Order #12345"
}'Response
{
"id": "pay_xyz789abc123",
"status": "authorized",
"amount": 15000,
"currency": "KZT",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "CardOnFile",
"shopper_interaction": "Ecommerce",
"payment_method": {
"type": "card",
"card": {
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2028
}
},
"created_at": "2026-03-25T14:20:00Z"
}For customer-initiated payments, 3D Secure authentication may be required.
Always handle the requires_action status and redirect the customer to
complete authentication.
Merchant-Initiated Payments
When you charge a customer without their active participation (e.g., subscription renewal, usage billing), use shopper_interaction: "ContractPresent".
Subscription Payments
For fixed-amount recurring charges on a regular schedule:
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 9900,
"currency": "USD",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "Subscription",
"shopper_interaction": "ContractPresent",
"description": "Pro Plan - April 2026",
"metadata": {
"subscription_id": "sub_abc123",
"billing_period": "2026-04"
}
}'Unscheduled Card-on-File Payments
For variable amounts or irregular timing (usage-based billing, account top-ups):
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4523,
"currency": "EUR",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "UnscheduledCardOnFile",
"shopper_interaction": "ContractPresent",
"description": "API usage charges - March 2026",
"metadata": {
"usage_type": "api_calls",
"period_start": "2026-03-01",
"period_end": "2026-03-31"
}
}'Merchant-initiated transactions (MIT) require prior customer consent. Ensure you have documented agreement from the customer before processing MIT payments.
Shopper Interaction Types
| Value | Description | When to Use |
|---|---|---|
Ecommerce | Customer-initiated online payment | Checkout, one-click pay buttons |
ContractPresent | Merchant-initiated under prior agreement | Subscriptions, scheduled billing, usage charges |
Understanding the Difference
Ecommerce (Customer-Initiated)
- Customer clicks a button to pay
- Customer is present during the transaction
- 3D Secure may be triggered
- Lower fraud risk, higher approval rates
ContractPresent (Merchant-Initiated)
- Merchant charges without customer interaction
- Customer previously agreed to future charges
- 3D Secure exemption applies
- Requires proper consent documentation
Handling 3D Secure
For customer-initiated payments, the card issuer may require 3D Secure authentication.
After creating a payment, check if authentication is required.
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 15000,
"currency": "KZT",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "CardOnFile",
"shopper_interaction": "Ecommerce",
"return_url": "https://yoursite.com/checkout/complete"
}'If the response status is requires_action, redirect the customer to the redirect_url returned in the response to complete 3DS authentication.
After authentication, the customer returns to your return_url. Retrieve the payment to check the final status.
curl https://api.plexypay.com/v2/payments/pay_xyz789abc123 \
-H "x-api-key: YOUR_API_KEY"Auto-Capture vs Manual Capture
By default, payments are authorized but not captured. You can control this behavior:
Auto-Capture
Set capture: true to capture immediately:
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 9900,
"currency": "USD",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "Subscription",
"shopper_interaction": "ContractPresent",
"capture": true
}'Manual Capture
Authorize first, then capture when ready (e.g., after shipping):
# Capture an authorized payment
curl -X POST https://api.plexypay.com/v2/payments/pay_xyz789abc123/capture \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 9900
}'Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Amount in smallest currency unit (cents, tiyn, etc.) |
currency | string | Yes | Three-letter ISO currency code |
token_id | string | Yes | The token ID from tokenization |
shopper_id | string | Yes | Customer identifier matching the token |
recurring_processing_model | string | Yes | CardOnFile, Subscription, or UnscheduledCardOnFile |
shopper_interaction | string | Yes | Ecommerce or ContractPresent |
capture | boolean | No | Auto-capture payment (default: false) |
description | string | No | Payment description for records |
metadata | object | No | Custom key-value data |
return_url | string | No* | URL for 3DS redirect return |
*Required for customer-initiated payments that may require 3D Secure
Error Handling
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 9900,
"currency": "USD",
"token_id": "tok_card_visa_4242",
"shopper_id": "shopper_123456",
"recurring_processing_model": "Subscription",
"shopper_interaction": "ContractPresent"
}'If the request fails, the API returns an error object with a code field. Common error codes include token_not_found, token_expired, insufficient_funds, card_declined, and shopper_mismatch.
Best Practices
For Subscription Payments
- Retry logic - Implement smart retries for failed payments
- Grace periods - Give customers time to update payment methods
- Notifications - Alert customers before and after charges
- Dunning management - Have a process for handling failed renewals
For Card-on-File Payments
- Confirm at checkout - Show saved card details before charging
- CVC re-entry - Consider asking for CVC on high-value orders
- Default payment method - Let customers set a preferred card
For All Token Payments
- Monitor decline rates - High declines may indicate token issues
- Keep tokens updated - Use Account Updater for automatic updates
- Handle expiration - Proactively request new cards before expiry
Testing
Use these test tokens to verify payment scenarios:
| Test Token | Result |
|---|---|
tok_test_success | Payment succeeds |
tok_test_declined | Card declined |
tok_test_insufficient_funds | Insufficient funds |
tok_test_3ds_required | 3D Secure challenge |
tok_test_expired | Card expired |
Next Steps
- Manage Tokens - List, update, and delete tokens
- Forward Payment Details - Share tokens with third parties
- 3D Secure - Learn about authentication requirements