Process Card Payments
You can process card payments using either Payment Intents or the direct Payments API. Both approaches result in a Payment object. Payment Intents are recommended for new integrations — they provide a durable, stateful lifecycle with built-in support for async outcomes and safe retries.
Now that you have completed the Collect Cards guide, let's process a card payment.
Getting Started
To get started, you will need a Credova Account.
Get your Secret Key
Next you will need your Secret Key. Go to your Developers section and click Reveal for your Secret Key and copy the value.
Payment Intents
A Payment Intent represents your intent to collect funds from a customer. It tracks the full lifecycle of a charge — creation, confirmation, processing, and the final succeeded state — and creates a Payment record on success.
Create a Payment Intent
Call the Create Payment Intent endpoint. Including a card at creation time starts the intent in requires_confirmation status and it is ready to confirm immediately:
curl 'https://api.publicsquare.com/payment_intents' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"amount": 1000,
"currency": "USD",
"capture_method": "automatic",
"payment_method": {
"card": "card_AjkCFKAYiTsjghXWMzoXFPMxj"
},
"customer": {
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@email.com"
},
"billing_details": {
"address_line_1": "111 Test St.",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
}
}'
{
"id": "pmt_int_2xNjK7abcdefghij",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "requires_confirmation",
"amount": 1000,
"currency": "USD",
"capture_method": "automatic",
"payment_method": {
"card": {
"id": "card_AjkCFKAYiTsjghXWMzoXFPMxj",
"last_four": "4242",
"brand": "visa",
"exp_month": "12",
"exp_year": "2025"
}
},
"payment_id": null,
"expires_date": "2026-04-16T14:22:10Z",
"created_date": "2026-04-15T14:22:10Z",
"modified_date": "2026-04-15T14:22:10Z"
}
Create Without a Payment Method
For multi-step checkout flows where the payment method is collected separately, omit the payment_method field. The intent starts in requires_payment_method status and the amount and other details can still be updated before a card is attached:
curl 'https://api.publicsquare.com/payment_intents' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"amount": 1000,
"currency": "USD",
"capture_method": "automatic"
}'
{
"id": "pmt_int_2xNjK7abcdefghij",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "requires_payment_method",
"amount": 1000,
"currency": "USD",
"capture_method": "automatic",
"payment_method": null,
"payment_id": null,
"expires_date": "2026-04-16T14:22:10Z",
"created_date": "2026-04-15T14:22:10Z",
"modified_date": "2026-04-15T14:22:10Z"
}
Once you have a card, call the Update Payment Intent endpoint to attach it. The intent will transition to requires_confirmation:
curl 'https://api.publicsquare.com/payment_intents/pmt_int_2xNjK7abcdefghij' \
-X 'PUT' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"payment_method": {
"card": "card_AjkCFKAYiTsjghXWMzoXFPMxj"
}
}'
Confirm the Payment Intent
With the intent in requires_confirmation, call the Confirm Payment Intent endpoint to submit the charge to the processor:
curl 'https://api.publicsquare.com/payment_intents/pmt_int_2xNjK7abcdefghij/confirm' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 3a9f1b72-cc4e-4f92-b7d3-1e5a9c8d2041' \
-H 'Content-Type: application/json'
When the processor responds quickly, you will receive a 200 with status: succeeded and a populated payment_id:
{
"id": "pmt_int_2xNjK7abcdefghij",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"amount": 1000,
"currency": "USD",
"payment_id": "pmt_5mBpT2ghiklmnopq",
"next_action": null,
"expires_date": null,
"succeeded_date": "2026-04-15T14:22:45Z",
"created_date": "2026-04-15T14:22:10Z",
"modified_date": "2026-04-15T14:22:45Z"
}
When the processor takes longer to respond, you will receive a 202 with status: processing:
{
"id": "pmt_int_2xNjK7abcdefghij",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "processing",
"amount": 1000,
"currency": "USD",
"payment_id": null,
"expires_date": "2026-04-15T14:52:10Z",
"created_date": "2026-04-15T14:22:10Z",
"modified_date": "2026-04-15T14:22:35Z"
}
202, subscribe to the payment-intents:update webhook event. The final outcome is in entity.status on the Payment Intent in the notification payload. See the Webhooks guide for setup instructions.{
"id": "evnt_5jxWRFNLCAWeegrkCAG3a9DGc",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "production",
"event_type": "payment-intents:update",
"entity_type": "PaymentIntent",
"entity_id": "pmt_int_2xNjK7abcdefghij",
"entity": {
"id": "pmt_int_2xNjK7abcdefghij",
"status": "succeeded",
"amount": 1000,
"currency": "USD",
"payment_id": "pmt_5mBpT2ghiklmnopq",
"succeeded_date": "2026-04-15T14:22:45Z",
"created_date": "2026-04-15T14:22:10Z",
"modified_date": "2026-04-15T14:22:45Z"
},
"created_at": "2026-04-15T14:22:45Z"
}
Handling Declines
If the card is hard-declined, the intent returns to requires_confirmation and the last_payment_error field is populated with the decline reason. You can attach a new payment method and re-confirm the same intent — no need to create a new one:
{
"id": "pmt_int_2xNjK7abcdefghij",
"status": "requires_confirmation",
"last_payment_error": {
"code": "card_declined",
"message": "Your card was declined."
},
...
}
Legacy
The direct Payments API provides a synchronous, single-request charge. The response contains the final payment result.
For example, given you have a previously collected card:
{
"id": "card_AjkCFKAYiTsjghXWMzoXFPMxj",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"cardholder_name": "John Smith",
"last4": "4242",
"exp_month": "12",
"exp_year": "2025",
"fingerprint": "CC2XvyoohnqecEq4r3FtXv6MdCx4TbaW1UUTdCCN5MNL",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
Create a Payment
We need to make a call to Create Payment endpoint:
curl 'https://api.publicsquare.com/payments' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPONTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"amount": 1000,
"currency": "USD",
"payment_method": {
"card": "card_AjkCFKAYiTsjghXWMzoXFPMxj"
},
"customer": {
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@email.com"
},
"billing_details": {
"address_line_1": "111 Test St.",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
}
}'
Payment Response
Given the above example, you should see a payment result similar to:
{
"id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"amount": 1000,
"amount_capturable": 0,
"amount_charged": 1000,
"amount_refunded": 0,
"refunded": false,
"currency": "USD",
"payment_method": {
"card": {
"id": "card_AjkCFKAYiTsjghXWMzoXFPMxj",
"cardholder_name": "John Smith",
"last4": "4242",
"exp_month": "12",
"exp_year": "2025",
"brand": "visa",
"avs_code": "Y",
"cvv2_reply": "M",
"fingerprint": "CC2XvyoohnqecEq4r3FtXv6MdCx4TbaW1UUTdCCN5MNL"
}
},
"customer": {
"id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@email.com"
},
"billing_details": {
"address_line_1": "111 Test St.",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
},
"transaction": {
"id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"amount": 1000,
"fee_amount": 0,
"net_amount": 1000,
"currency": "USD",
"type_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"type": "payment",
"processor": "nuvei",
"processor_id": "7110000000010554769",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
},
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
Conclusion
Now that we have seen how to process payments with a collected card, we may need to manage the payment or view information about the payment. Follow these guides to learn more: