Payment Docs
Payment methods

Card payments (H2H)

Accept card data on your own page and drive the 3-D Secure flow through the API

Before you start

This payment method is not enabled for all merchants. Check availability with your manager.

Overview

There are two ways to accept cards:

OptionWho collects card dataRequirements
Hosted payment page (default)Our payment pageNone: create a regular order
Host-to-host (H2H), this pageYour pagePCI DSS compliance, enabled by manager

With H2H you create an order, send the card data to the API and drive the verification (3-D Secure, SMS code) yourself. The payer never leaves your site.

Flow

Create an order

Create a regular order and save its id.

Create payment

Send card data

POST /v1/orders/{orderId}/h2h/card
FieldTypeRequiredDescription
cardNumberstring✅ YesCard number
expiryDatestring✅ YesExpiry date, MM/YY
cardholderNamestring✅ YesCardholder name
cvvstring✅ YesCVV / CVC code
curl -X POST "https://api.riopay.online/v1/orders/{orderId}/h2h/card" \
  -H "Content-Type: application/json" \
  -H "X-Api-Token: YOUR_API_TOKEN" \
  -d '{
    "cardNumber": "4111111111111111",
    "expiryDate": "12/25",
    "cardholderName": "John Doe",
    "cvv": "123"
  }'

If the response contains the order object, the card data was accepted. Next, check whether an SMS code is required.

Check the H2H status

GET /v1/orders/{orderId}/h2h/status
curl -X GET "https://api.riopay.online/v1/orders/{orderId}/h2h/status" \
  -H "X-Api-Token: YOUR_API_TOKEN"
{
  "isSmsRequired": true,
  "status": "PROCESSING"
}
FieldDescription
isSmsRequiredtrue: ask the payer for the code from their bank SMS
statusCurrent H2H status, see H2H statuses

Poll this endpoint while the status is INITIALIZING or PROCESSING.

Send the SMS code (if required)

You pass the code that the payer received from their bank to the API. This endpoint does not send an SMS to the payer.

POST /v1/orders/{orderId}/h2h/code
curl -X POST "https://api.riopay.online/v1/orders/{orderId}/h2h/code" \
  -H "Content-Type: application/json" \
  -H "X-Api-Token: YOUR_API_TOKEN" \
  -d '{ "code": "123456" }'

After a successful response keep checking the H2H status. If isSmsRequired becomes true again, the code was wrong: ask the payer for a new one.

Wait for the final order status

SUCCESS at the H2H level means the card stage is complete, not that the funds arrived. The final result comes as the order status via webhook or GET /v1/orders/{orderId}.

Order status and webhooks

H2H statuses

H2H statuses describe the card verification stage only and are not the order statuses. Always confirm the final result with the order status.

StatusFinalDescription
INITIALIZINGNoH2H session is initializing
PROCESSINGNoProcessing: validation, 3-D Secure, anti-fraud checks
SUCCESSYesH2H stage completed successfully; wait for the final order status via webhook
CANCELLEDYesH2H payment cancelled
FAILEDYesH2H failed with an error
EXPIREDYesH2H session expired
  • Poll while INITIALIZING or PROCESSING.
  • On SUCCESS, wait for the order webhook.
  • On CANCELLED, FAILED or EXPIRED, stop polling and record the failure; create a new order to retry.

Card details in the order request

Some terminals accept card details directly in POST /v1/orders through the card object, together with full payer details. This also requires PCI DSS compliance and is enabled per merchant.

Card fields

FieldTypeRequiredDescription
cardholderNamestring✅ YesCardholder name
cardNumberstring✅ YesCard number
cvvstring✅ YesCVV / CVC code
expiryDatestring✅ YesExpiry date, MM/YY

Customer fields

FieldTypeRequiredDescription
emailstring✅ YesPayer email
phonestring✅ YesPhone number
firstNamestring✅ YesFirst name
lastNamestring✅ YesLast name
birthdaystring✅ YesDate of birth, YYYY-MM-DD
countrystring✅ YesCountry, ISO 3166-1 alpha-2
citystring✅ YesCity
regionstring✅ YesState or region
postcodestring✅ YesPostal code
addressstring✅ YesStreet address

Request example

{
  "amount": "10.99",
  "currency": "EUR",
  "successUrl": "https://example.com/success",
  "failUrl": "https://example.com/fail",
  "card": {
    "cardholderName": "Jane Doe",
    "cardNumber": "4444444444444444",
    "cvv": "123",
    "expiryDate": "12/26"
  },
  "customer": {
    "email": "customer@example.com",
    "phone": "1999999999",
    "firstName": "Jane",
    "lastName": "Doe",
    "birthday": "2000-05-05",
    "country": "PT",
    "city": "Maia",
    "region": "Porto",
    "postcode": "4450",
    "address": "Rua Example 1"
  }
}

Some terminals only need the payer's email for card payments on the hosted page:

{
  "amount": "10.99",
  "currency": "EUR",
  "successUrl": "https://example.com/success",
  "failUrl": "https://example.com/fail",
  "customer": {
    "email": "customer@example.com"
  }
}

Which of these request shapes applies to you depends on the terminal. Confirm with your manager before integrating.

Next steps

On this page