Collect a C2P payment
C2P is a three-step tenant flow: create an intent (bank SMS when supported), collect the customer’s token, then execute.
Check which methods you can offer
GET /v1/payment-methods lists the bolívar methods your account can take right now — pago_movil, c2p and vpos — each with available and, when false, a reason: not_enabled, receiving_account_not_configured (Pago Móvil) or provider_not_configured. Cache it for a few minutes and hide what is not available.
curl "${API_URL}/v1/payment-methods" \
--header "x-api-key: ${VEXPAY_API_KEY}"{
"livemode": true,
"methods": [
{ "method": "pago_movil", "available": true },
{ "method": "c2p", "available": true },
{ "method": "vpos", "available": false, "reason": "not_enabled" }
]
}Three-step lifecycle
- Request an intent
Send the amount, customer identity (cédula), phone, and bank code to POST /v1/payments/c2p/request. When supported, the gateway instructs the payer bank to SMS an OTP (
otpRequested: true). - Collect the token
Ask the customer for the 6–8 digit OTP they received from their bank (or generated in their bank app when otpRequested is false).
- Execute the charge
Send the token with the same payment details and returned intentId to POST /v1/payments/c2p. Usually the response is COMPLETED. With some banks the debit is confirmed a little later: the response is then status PENDING, and the final result arrives as payment.completed or payment.failed (usually within minutes, at most 24 hours). Treat PENDING as "processing" and fulfil the order only on payment.completed.
1. Request an intent
curl --request POST "${API_URL}/v1/payments/c2p/request" \
--header "content-type: application/json" \
--header "x-api-key: ${VEXPAY_API_KEY}" \
--data '{
"usdAmount": 12.50,
"debtorId": "V12345678",
"debtorCellPhone": "584121234567",
"debtorBankCode": 102,
"externalRef": "order_demo_1042"
}'2. Execute with the token
curl --request POST "${API_URL}/v1/payments/c2p" \
--header "content-type: application/json" \
--header "x-api-key: ${VEXPAY_API_KEY}" \
--data '{
"intentId": "00000000-0000-4000-8000-000000000000",
"usdAmount": 12.50,
"debtorId": "V12345678",
"debtorCellPhone": "584121234567",
"debtorBankCode": 102,
"token": "123456",
"externalRef": "order_demo_1042"
}'const payment = await fetch(
`${process.env.API_URL}/v1/payments/c2p`,
{
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': process.env.VEXPAY_API_KEY,
},
body: JSON.stringify({
intentId,
usdAmount: 12.5,
debtorId: 'V12345678',
debtorCellPhone: '584121234567',
debtorBankCode: 102,
token: customerProvidedToken,
externalRef: 'order_demo_1042',
}),
}
);