Send card payments
What you will learn
✅ How to create a card token
✅ How to send a push payment (send funds to a card)
✅ How to send a pull payment (request funds from a card)
✅ How to test rejected scenarios
If you are new to card payments, check out the Card payments overview.
This tutorial assumes familiarity with APIs. For more information, visit API Basics.
This tutorial uses these API endpoints:
API | Description |
|---|---|
Card tokens | Creates a card token by validating the card with the card network |
Sends a push or pull payment to or from a debit card | |
Retrieves payment details |
Before you begin
Make sure you have:
- Your partner ID
- Your product ID
- An account number
- Register the following webhook events:
Webhook | Description |
|---|---|
CardPayments.Card.Approved | Card token authorization approved by the card network |
CardPayments.Card.Rejected | Card token authorization rejected by the card network |
CardPayments.Payment.Cleared | Payment passed hold evaluations and is being processed |
CardPayments.Payment.Completed | Payment transaction successfully completed |
CardPayments.Payment.Rejected | Payment transaction rejected by the issuing bank or network |
CardPayments.Payment.Failed | Payment failed to submit (validation error or system issue) |
You should be familiar with these terms:
Term | Definition |
|---|---|
Card token | A secure representation of a card number that can be used for transactions without storing the PAN |
PAN | Primary Account Number - the full card number on the front of a debit card |
Push payment | Sending funds from your account to a cardholder's debit card |
Pull payment | Requesting funds from a cardholder's debit card to your account |
Corresponding entity | Information about the sender (for push) or receiver (for pull) of funds |
Create a card token
Before you can send a payment, you must create a card token. Card tokenization converts the cardholder's PAN (card number) into a secure token. Cross River validates the card with the card network. This confirms it can receive or send payments.
Cross River does not store card numbers. Once tokenized, all future transactions use the token.
In this tutorial, you will tokenize a test card for Alice Johnson. You can use sample cards for testing in the sandbox environment.
Call POST /cardpayments/v1/cardtokens.
For this call, these attributes are required:
Attribute | Description |
|---|---|
productId | Your unique product ID in COS |
accountNumber | The account number associated with this card token |
firstName | Cardholder's first name (1-35 characters) |
lastName | Cardholder's last name (1-35 characters) |
pan | The full card number |
expirationMonth | Card expiration month (1-12) |
expirationYear | Card expiration year (4 digits) |
IMPORTANT
We strongly recommend that you include an Idempotency in the request header to prevent duplicate card tokens in case of a failure.
The address object is optional but recommended. When provided, the card network may perform address verification.
POST /cardpayments/v1/cardtokens
{
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"accountNumber": "2287979807",
"clientIdentifier": "token-alice-001",
"firstName": "Alice",
"lastName": "Johnson",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
},
"phone": "5035551234",
"emailAddress": "[email protected]",
"pan": "5102589999999905",
"expirationMonth": 12,
"expirationYear": 2028,
"cvv": "123"
}A successful API call returns a JSON response containing the card token details.
Key attributes in the response:
- id - The unique card token ID
- token - The tokenized representation of the card (use this for payments)
- authorizationStatus - Either Approved or Rejected
- capabilities - Shows what payment types the card supports
{
"id": "26acd726-dade-4064-996a-b42b00b634df",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"accountNumber": "2287979807",
"token": "11FB445C487140A9BEA51457A796172A000000",
"authorizationStatus": "Approved",
"statusReasonCode": "00",
"statusReasonDescription": "Approved and completed successfully",
"isAuthorized": true,
"firstName": "Alice",
"lastName": "Johnson",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
},
"isAddressVerified": false,
"accountNameInquiryUsed": "Used",
"accountNameInquiryResult": "Match",
"phone": "5035551234",
"emailAddress": "[email protected]",
"binNumber": "510258",
"panLastFour": "9905",
"expirationMonth": 12,
"expirationYear": 2028,
"cardFingerprint": "7BleaDLyA+3nxDUkoX6WjE0GKUHvEniZuoJFFjVd0muNYH4P3VOoV0w5LX3JW4h75OMx50mIRTS6xnpcxLX/2w==",
"isExpired": false,
"cardBrand": "Mastercard",
"capabilities": {
"fastFundsSupported": true,
"domesticPushEnabled": true,
"domesticPullEnabled": true,
"internationalPushEnabled": false,
"internationalPullEnabled": false
},
"issuerCountryCode": "US",
"clientIdentifier": "token-alice-001",
"createdAt": "2026-05-10T15:30:23.6206088-04:00",
"isActive": true,
"authorizedAt": "2026-05-10T15:30:24.1757549-04:00",
"lastModifiedAt": "2026-05-10T15:30:24.1757549-04:00"
}The authorizationStatus of Approved confirms that the card network validated this card. You can use it for payments. Check the capabilities object to see which payment types are supported.
The CardPayments.Card.Approved webhook event is triggered when the card network approves the card token.
{
"id": "7af80bc3-4f1c-4842-b60e-ad9400fb59db",
"eventName": "CardPayments.Card.Approved",
"status": "Pending",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"createdAt": "2026-05-10T15:30:24.623-04:00",
"resources": [
"cardpayments/v1/cardtokens/26acd726-dade-4064-996a-b42b00b634df"
],
"details": {
"cardId": "26acd726-dade-4064-996a-b42b00b634df",
"clientIdentifier": "token-alice-001",
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"cardBrand": "Mastercard",
"panLastFour": "9905",
"authorizationStatus": "Approved"
}
}Send a push payment
Push payments send funds from your Cross River account to a cardholder's debit card. Funds typically reach the cardholder within minutes. Timing depends on the card network and issuing bank.
In this example, you will send $25.00 from your account to Alice Johnson's card.
Call POST /cardpayments/v1/payments.
For this call, these attributes are required:
Attribute | Description |
|---|---|
accountNumber | Your Cross River account number (funds will be debited from this account) |
cardToken | The token from the card token creation response |
amount | The amount in cents (e.g., 2500 = $25.00) |
paymentType | Set to Push for sending funds to a card |
businessType | Two-character code indicating the transaction type (e.g., P2P, B2C, B2B) |
Amounts are specified in cents without decimal points. For example, $25.00 is written as 2500.
POST /cardpayments/v1/payments
{
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"cardToken": "11FB445C487140A9BEA51457A796172A000000",
"accountNumber": "2287979807",
"amount": 2500,
"paymentType": "Push",
"correspondingEntity": {
"firstName": "Alice",
"lastName": "Johnson",
"externalAccountIdentifier": "****9905",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
}
},
"businessType": "P2P",
"clientIdentifier": "payment-push-001"
}A successful API call returns a JSON response with the payment details.
The status attribute shows the current payment state. For a newly created payment, the status is typically Created.
{
"id": "d706c741-e556-4101-a849-b42b00bfd7e9",
"clientIdentifier": "payment-push-001",
"amount": 2500,
"paymentType": "Push",
"status": "Created",
"source": "Api",
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"cardId": "26acd726-dade-4064-996a-b42b00b634df",
"cardToken": "11FB445C487140A9BEA51457A796172A000000",
"cardBrand": "Mastercard",
"panLastFour": "9905",
"issuerCountryCode": "US",
"correspondingEntity": {
"firstName": "Alice",
"lastName": "Johnson",
"externalAccountIdentifier": "****9905",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
}
},
"accountNumber": "2287979807",
"businessType": "P2P",
"wasRefunded": false,
"createdAt": "2026-05-10T15:35:28.8271201-04:00",
"limitsEligibleOn": "2026-05-10T15:35:28.8271201-04:00",
"lastModifiedAt": "2026-05-10T15:35:28.9388613-04:00"
}The status of Created indicates the payment was accepted and is being processed. The payment is not complete yet.
Push payment webhook flow
The payment goes through multiple stages, each triggering a webhook event:
Payment cleared
The CardPayments.Payment.Cleared event fires when the payment passes internal hold evaluations. The system then submits it to the card network.
{
"id": "8c2a3b12-16c5-49db-84d8-b38a00fa1b2c",
"eventName": "CardPayments.Payment.Cleared",
"status": "Pending",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"createdAt": "2026-05-10T15:35:29.417-04:00",
"resources": [
"cardpayments/v1/payments/d706c741-e556-4101-a849-b42b00bfd7e9"
],
"details": {
"paymentId": "d706c741-e556-4101-a849-b42b00bfd7e9",
"paymentType": "Push",
"amount": "2500",
"retrievalReferenceId": null,
"traceNumber": null,
"reasonCode": null,
"reasonDescription": null,
"clientIdentifier": "payment-push-001",
"coreTransactionId": "18b8597a-393f-483d-9897-b42c00aa5788"
}
}Payment completed
The CardPayments.Payment.Completed event fires when the payment is approved. This confirms the funds have been successfully transferred.
{
"id": "9f3e5c67-9dd3-48e1-9488-b1720104c696",
"eventName": "CardPayments.Payment.Completed",
"status": "Pending",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"createdAt": "2026-05-10T15:35:32.150-04:00",
"resources": [
"cardpayments/v1/payments/d706c741-e556-4101-a849-b42b00bfd7e9"
],
"details": {
"paymentId": "d706c741-e556-4101-a849-b42b00bfd7e9",
"paymentType": "Push",
"amount": "2500",
"retrievalReferenceId": "413715103005",
"traceNumber": "103005",
"reasonCode": "00",
"reasonDescription": "Approved",
"clientIdentifier": "payment-push-001",
"coreTransactionId": "18b8597a-393f-483d-9897-b42c00aa5788"
}
}The reasonCode of 00 and reasonDescription of Approved confirm the payment was successful.
Send a pull payment
Pull payments request funds from a cardholder's debit card to your Cross River account. This is commonly used for collecting payments from customers.
In this example, you will request $15.50 from Alice Johnson's card.
Call POST /cardpayments/v1/payments.
The request is nearly identical to a push payment, except:
- Set paymentType to Pull
- The correspondingEntity represents the payer (the person whose card is being charged)
POST /cardpayments/v1/payments
{
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"cardToken": "11FB445C487140A9BEA51457A796172A000000",
"accountNumber": "2287979807",
"amount": 1550,
"paymentType": "Pull",
"correspondingEntity": {
"firstName": "Alice",
"lastName": "Johnson",
"externalAccountIdentifier": "****9905",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
}
},
"businessType": "P2P",
"clientIdentifier": "payment-pull-001"
}The response structure is the same as push payments, with paymentType set to Pull.
{
"id": "f8c4d823-7a21-4956-b7e2-c93b01aef4d2",
"clientIdentifier": "payment-pull-001",
"amount": 1550,
"paymentType": "Pull",
"status": "Created",
"source": "Api",
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"cardId": "26acd726-dade-4064-996a-b42b00b634df",
"cardToken": "11FB445C487140A9BEA51457A796172A000000",
"cardBrand": "Mastercard",
"panLastFour": "9905",
"issuerCountryCode": "US",
"correspondingEntity": {
"firstName": "Alice",
"lastName": "Johnson",
"externalAccountIdentifier": "****9905",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
}
},
"accountNumber": "2287979807",
"businessType": "P2P",
"wasRefunded": false,
"createdAt": "2026-05-10T15:40:15.2134567-04:00",
"limitsEligibleOn": "2026-05-10T15:40:15.2134567-04:00",
"lastModifiedAt": "2026-05-10T15:40:15.3245678-04:00"
}Pull payments follow the same webhook flow as push payments (Cleared → Completed), with the same event structure.
Test rejected scenarios
You can test various rejection scenarios in the sandbox environment to understand how your application should handle failures.
Simulate rejected card authorization
To test a card token rejection, use a test card number that triggers a specific rejection response.
Call POST /cardpayments/v1/cardtokens using a test card that will be rejected.
Use the Visa test card 4000289999999906 which simulates a card that fails authorization checks.
POST /cardpayments/v1/cardtokens
{
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"accountNumber": "2287979807",
"firstName": "Test",
"lastName": "Reject",
"address": {
"street1": "123 Test Street",
"city": "New York",
"state": "NY",
"postalCode": "10001",
"countryCode": "US"
},
"pan": "4000289999999906",
"expirationMonth": 12,
"expirationYear": 2028,
"cvv": "123"
}The response shows authorizationStatus of Rejected.
{
"id": "ee7870ba-5ef7-4700-92ed-bed8a77abe7c",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"accountNumber": "2287979807",
"token": null,
"authorizationStatus": "Rejected",
"statusReasonCode": "14",
"statusReasonDescription": "Invalid card number",
"isAuthorized": false,
"firstName": "Test",
"lastName": "Reject",
"panLastFour": "9906",
"cardBrand": "Visa",
"isActive": false,
"createdAt": "2026-05-10T15:45:23.6206088-04:00"
}The CardPayments.Card.Rejected webhook event is triggered.
{
"id": "3c8f6a21-dc90-48ea-b642-b04a0126580f",
"eventName": "CardPayments.Card.Rejected",
"status": "Pending",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"createdAt": "2026-05-10T15:45:24.417-04:00",
"resources": [
"cardpayments/v1/cardtokens/ee7870ba-5ef7-4700-92ed-bed8a77abe7c"
],
"details": {
"cardId": "ee7870ba-5ef7-4700-92ed-bed8a77abe7c",
"clientIdentifier": null,
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"cardBrand": "Visa",
"panLastFour": "9906",
"authorizationStatus": "Rejected"
}
}Simulate rejected payment
To test a payment rejection (after successful card tokenization), provide invalid or missing required data.
Call POST /cardpayments/v1/payments with missing required fields in the correspondingEntity object.
POST /cardpayments/v1/payments
{
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"cardToken": "11FB445C487140A9BEA51457A796172A000000",
"accountNumber": "2287979807",
"amount": 1000,
"paymentType": "Push",
"correspondingEntity": {
"firstName": "Alice",
"lastName": "Johnson"
},
"businessType": "P2P"
}The CardPayments.Payment.Failed event fires when the payment fails validation.
{
"id": "eb8f80f8-6e1c-428f-be54-b1720103ea5d",
"eventName": "CardPayments.Payment.Failed",
"status": "Pending",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"createdAt": "2026-05-10T15:50:18.603-04:00",
"resources": [
"cardpayments/v1/payments/eb8f80f8-6e1c-428f-be54-b1720103ea5d"
],
"details": {
"paymentId": "eb8f80f8-6e1c-428f-be54-b1720103ea5d",
"paymentType": "Push",
"amount": "1000",
"retrievalReferenceId": null,
"traceNumber": null,
"reasonCode": "1000",
"reasonDescription": "AddressLine1 for corresponding entity is required.",
"clientIdentifier": null,
"coreTransactionId": null
}
}The reasonCode and reasonDescription provide details about why the payment failed.
Verify payment status
You can retrieve the current status of any payment at any time.
Call GET /cardpayments/v1/payments/{id} using the payment ID from the response.
GET /cardpayments/v1/payments/d706c741-e556-4101-a849-b42b00bfd7e9The response includes the current payment status and all transaction details.
{
"id": "d706c741-e556-4101-a849-b42b00bfd7e9",
"clientIdentifier": "payment-push-001",
"amount": 2500,
"paymentType": "Push",
"status": "Completed",
"source": "Api",
"productId": "31cae717-408e-4813-a6b1-ad6600e48632",
"partnerId": "82a1cfb9-de92-4cc2-8a74-ad6600e36d7a",
"cardId": "26acd726-dade-4064-996a-b42b00b634df",
"cardToken": "11FB445C487140A9BEA51457A796172A000000",
"cardBrand": "Mastercard",
"panLastFour": "9905",
"retrievalReferenceId": "413715103005",
"traceNumber": "103005",
"statusReasonCode": "00",
"statusReasonDescription": "Approved",
"issuerCountryCode": "US",
"correspondingEntity": {
"firstName": "Alice",
"lastName": "Johnson",
"externalAccountIdentifier": "****9905",
"address": {
"street1": "456 Oak Avenue",
"street2": "Apt 12B",
"city": "Portland",
"state": "OR",
"postalCode": "97201",
"countryCode": "US"
}
},
"accountNumber": "2287979807",
"businessType": "P2P",
"wasRefunded": false,
"createdAt": "2026-05-10T15:35:28.8271201-04:00",
"completedAt": "2026-05-10T15:35:32.4567890-04:00",
"limitsEligibleOn": "2026-05-10T15:35:28.8271201-04:00",
"lastModifiedAt": "2026-05-10T15:35:32.4567890-04:00"
}The status of Completed and completedAt timestamp confirm the payment successfully processed.