Idempotency
Protection against duplicate financial operations.
Rapyd provides an optional idempotency check for API requests. To activate the check, include the idempotency
parameter in the header of the request. If the idempotency
header value is the same in another request in the next 24 hours, the second request is determined to be idempotent and the response to the first request is returned again.
By default, the client configuration enables the idempotency check for Create Paymentrequests only. This check considers the value of the idempotency
header and the value of the amount
parameter in the body of the request. See Idempotency Check for Create Payment, below.
On request, Rapyd Client Support will change your client configuration to allow idempotency checks on all POST and PUT requests. With this configuration, the idempotency check evaluates only the idempotency
header, even in 'Create Payment' requests.
Idempotency Check for Create Payment
When your client configuration enables the idempotency check for 'Create Payment' only, the value of the amount
field is relevant.
Note
The idempotency check does not examine the value of the currency
field, so requests for 24.00 euros and 24.00 dollars are idempotent if they use the same idempotency
header value.
Example #1 - Not idempotent
The following example illustrates two requests that use the same idempotency
header value. They are not idempotent because they have different values for amount
. In the responses, you can see that the id
field is different.
Request #1
curl --location --request POST 'https://sandboxapi.rapyd.net/v1/payments' \ --header 'Content-Type: application/json' \ --header 'access_key: 48873' \ --header 'salt: 90ec80e9' \ --header 'timestamp: 1565511756' \ --header 'signature: ZTFjZmUmZTw==' \ --header 'idempotency: 123' \ --data-raw { "amount": 100, "currency": "USD", "payment_method": { "type": "us_mastercard_card", "fields": { "number": "4111111111111111", "expiration_month": "12", "expiration_year": "23", "name": "John Doe", "cvv": "345" }, "metadata": { "merchant_defined": true } } }
Response #1
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "19072d56-7834-447a-9260-7c8c8da62b06" }, "data": { "id": "payment_ab30fc5ed6578b415ca7ba004b34d463", "amount": 100, "original_amount": 100, "is_partial": false, "currency_code": "USD", "country_code": "US", "status": "CLO", "description": "", "merchant_reference_id": "", "customer_token": "cus_1a4df69a959e184fd50884644f46cd73", "payment_method": "card_1ccfdb70c1b34d68ea2c09a15df1310c", "expiration": "0", "captured": true, "refunded": false, "refunded_amount": 0, "receipt_email": "", "redirect_url": "", "complete_payment_url": "", "error_payment_url": "", "receipt_number": "", "flow_type": "", "address": null, "statement_descriptor": "", "transaction_id": "", "created_at": "1565511756", "metadata": {}, "failure_code": "", "failure_message": "", "paid": true, "paid_at": 1565511756, "dispute": null, "refunds": null, "order": null, "outcome": null, "visual_codes": {}, "textual_codes": {}, "instructions": [], "ewallet_id": null, "ewallets": [], "payment_method_options": {}, "payment_method_type": "us_mastercard_card", "payment_method_type_category": "card", "fx_rate": 0, "merchant_requested_currency": null, "merchant_requested_amount": null, "payment_fees": null, "invoice": "", "escrow": null } }
Non-idempotent request #2
curl --location --request POST 'https://sandboxapi.rapyd.net/v1/payments' \ --header 'Content-Type: application/json' \ --header 'access_key: 48873' \ --header 'salt: 90ec80e9' \ --header 'timestamp: 1565511799' \ --header 'signature: ZTFjZmUmZTw==' \ --header 'idempotency: 123' \ --data-raw { "amount": 25, "currency": "USD", "payment_method": { "type": "us_mastercard_card", "fields": { "number": "4111111111111111", "expiration_month": "12", "expiration_year": "23", "name": "John Doe", "cvv": "345" }, "metadata": { "merchant_defined": true } } }
Response #2
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "68dd5bba-3358-408c-9207-5dc73935ab6d" }, "data": { "id": "payment_3badcd504599a0630cc4fe87cde8dfb5", "amount": 25, "original_amount": 25, "is_partial": false, "currency_code": "USD", "country_code": "US", "status": "CLO", "description": "", "merchant_reference_id": "", "customer_token": "cus_ed007e7d1d9d2f773f89c175f6b05bfa", "payment_method": "card_f23c1c0bcfd1019ee4e60e2a7f431420", "expiration": "0", "captured": true, "refunded": false, "refunded_amount": 0, "receipt_email": "", "redirect_url": "", "complete_payment_url": "", "error_payment_url": "", "receipt_number": "", "flow_type": "", "address": null, "statement_descriptor": "", "transaction_id": "", "created_at": "1565511799", "metadata": {}, "failure_code": "", "failure_message": "", "paid": true, "paid_at": 1565511799, "dispute": null, "refunds": null, "order": null, "outcome": null, "visual_codes": {}, "textual_codes": {}, "instructions": [], "ewallet_id": null, "ewallets": [], "payment_method_options": {}, "payment_method_type": "us_mastercard_card", "payment_method_type_category": "card", "fx_rate": 0, "merchant_requested_currency": null, "merchant_requested_amount": null, "payment_fees": null, "invoice": "", "escrow": null } }
Example #2 - Idempotent
The following example illustrates two idempotent requests. They use the same idempotency
header value. Note the value of the amount
field. In the responses, you can see that the id
field is the same.
Request #1
curl --location --request POST 'https://sandboxapi.rapyd.net/v1/payments' \ --header 'Content-Type: application/json' \ --header 'access_key: 48873' \ --header 'salt: 90ec80e9' \ --header 'timestamp: 1565511846' \ --header 'signature: ZTFjZmUmZTw==' \ --header 'idempotency: 1234' \ --data-raw { "amount": 57, "currency": "USD", "payment_method": { "type": "us_mastercard_card", "fields": { "number": "4111111111111111", "expiration_month": "12", "expiration_year": "23", "name": "John Doe", "cvv": "345" }, "metadata": { "merchant_defined": true } } }
Response #1
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "8b354b86-db72-4784-af3b-6421b89e1d12" }, "data": { "id": "payment_ca36b3dc4d55d46310c9e7763e12d3e2", "amount": 57, "original_amount": 57, "is_partial": false, "currency_code": "USD", "country_code": "US", "status": "CLO", "description": "", "merchant_reference_id": "", "customer_token": "cus_21bc82061221f9f797989a977baeae67", "payment_method": "card_9b04b0bb4a395ef84ffcf796972320d2", "expiration": "0", "captured": true, "refunded": false, "refunded_amount": 0, "receipt_email": "", "redirect_url": "", "complete_payment_url": "", "error_payment_url": "", "receipt_number": "", "flow_type": "", "address": null, "statement_descriptor": "", "transaction_id": "", "created_at": "1565511846", "metadata": {}, "failure_code": "", "failure_message": "", "paid": true, "paid_at": 1565511847, "dispute": null, "refunds": null, "order": null, "outcome": null, "visual_codes": {}, "textual_codes": {}, "instructions": [], "ewallet_id": null, "ewallets": [], "payment_method_options": {}, "payment_method_type": "us_mastercard_card", "payment_method_type_category": "card", "fx_rate": 0, "merchant_requested_currency": null, "merchant_requested_amount": null, "payment_fees": null, "invoice": "", "escrow": null } }
Idempotent request #2
curl --location --request POST 'https://sandboxapi.rapyd.net/v1/payments' \ --header 'Content-Type: application/json' \ --header 'access_key: 48873' \ --header 'salt: 90ec80e9' \ --header 'timestamp: 1565511846' \ --header 'signature: ZTFjZmUmZTw==' \ --header 'idempotency: 1234' \ --data-raw { "amount": 57, "currency": "USD", "payment_method": { "type": "us_mastercard_card", "fields": { "number": "4111111111111111", "expiration_month": "12", "expiration_year": "23", "name": "John Doe", "cvv": "345" }, "metadata": { "merchant_defined": true } } }
Response #2
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "8b354b86-db72-4784-af3b-6421b89e1d12" }, "data": { "id": "payment_ca36b3dc4d55d46310c9e7763e12d3e2", "amount": 57, "original_amount": 57, "is_partial": false, "currency_code": "USD", "country_code": "US", "status": "CLO", "description": "", "merchant_reference_id": "", "customer_token": "cus_21bc82061221f9f797989a977baeae67", "payment_method": "card_9b04b0bb4a395ef84ffcf796972320d2", "expiration": "0", "captured": true, "refunded": false, "refunded_amount": 0, "receipt_email": "", "redirect_url": "", "complete_payment_url": "", "error_payment_url": "", "receipt_number": "", "flow_type": "", "address": null, "statement_descriptor": "", "transaction_id": "", "created_at": "1565511846", "metadata": {}, "failure_code": "", "failure_message": "", "paid": true, "paid_at": 1565511847, "dispute": null, "refunds": null, "order": null, "outcome": null, "visual_codes": {}, "textual_codes": {}, "instructions": [], "ewallet_id": null, "ewallets": [], "payment_method_options": {}, "payment_method_type": "us_mastercard_card", "payment_method_type_category": "card", "fx_rate": 0, "merchant_requested_currency": null, "merchant_requested_amount": null, "payment_fees": null, "invoice": "", "escrow": null } }
Note that the response to the idempotent second request is identical to the response to the first request.
Example #3 - Idempotent
The following example illustrates two idempotent requests. They use the same idempotency
header value. Note that the values of the currency
field are different, and the payment method is different. In the responses, you can see that the id
field is the same.
Request #1
curl --location --request POST 'https://sandboxapi.rapyd.net/v1/payments' \ --header 'Content-Type: application/json' \ --header 'access_key: 48873' \ --header 'salt: 90ec80e9' \ --header 'timestamp: 1565512168' \ --header 'signature: ZTFjZmUmZTw==' \ --header 'idempotency: 12345' \ --data-raw { "amount": 15.65, "currency": "USD", "payment_method": { "type": "us_mastercard_card", "fields": { "number": "4111111111111111", "expiration_month": "12", "expiration_year": "23", "name": "John Doe", "cvv": "345" }, "metadata": { "merchant_defined": true } } }
Response #1
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "0b637672-085a-45d0-9432-2072d7fb4e83" }, "data": { "id": "payment_11109b0c4a35741609f30e55725de43a", "amount": 15.65, "original_amount": 15.65, "is_partial": false, "currency_code": "USD", "country_code": "US", "status": "CLO", "description": "", "merchant_reference_id": "", "customer_token": "cus_ad6f397fa6635f585471f1d74daaff74", "payment_method": "card_6e1f496be2f47dc011f4412eaf1fd36f", "expiration": "0", "captured": true, "refunded": false, "refunded_amount": 0, "receipt_email": "", "redirect_url": "", "complete_payment_url": "", "error_payment_url": "", "receipt_number": "", "flow_type": "", "address": null, "statement_descriptor": "", "transaction_id": "", "created_at": "1565512168", "metadata": {}, "failure_code": "", "failure_message": "", "paid": true, "paid_at": 1565512168, "dispute": null, "refunds": null, "order": null, "outcome": null, "visual_codes": {}, "textual_codes": {}, "instructions": [], "ewallet_id": null, "ewallets": [], "payment_method_options": {}, "payment_method_type": "us_mastercard_card", "payment_method_type_category": "card", "fx_rate": 0, "merchant_requested_currency": null, "merchant_requested_amount": null, "payment_fees": null, "invoice": "", "escrow": null } }
Non-identical request #2
curl --location --request POST 'https://sandboxapi.rapyd.net/v1/payments' \ --header 'Content-Type: application/json' \ --header 'access_key: 48873' \ --header 'salt: 90ec80e9' \ --header 'timestamp: 1565512168' \ --header 'signature: ZTFjZmUmZTw==' \ --header 'idempotency: 12345' \ --data-raw { "amount": 15.65, "currency": "MXN", "payment_method": { "type": "mx_santander_bank", "fields": {} }, "metadata": { "merchant_defined": true } }
Response #2
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "0b637672-085a-45d0-9432-2072d7fb4e83" }, "data": { "id": "payment_11109b0c4a35741609f30e55725de43a", "amount": 15.65, "original_amount": 15.65, "is_partial": false, "currency_code": "USD", "country_code": "US", "status": "CLO", "description": "", "merchant_reference_id": "", "customer_token": "cus_ad6f397fa6635f585471f1d74daaff74", "payment_method": "card_6e1f496be2f47dc011f4412eaf1fd36f", "expiration": "0", "captured": true, "refunded": false, "refunded_amount": 0, "receipt_email": "", "redirect_url": "", "complete_payment_url": "", "error_payment_url": "", "receipt_number": "", "flow_type": "", "address": null, "statement_descriptor": "", "transaction_id": "", "created_at": "1565512168", "metadata": {}, "failure_code": "", "failure_message": "", "paid": true, "paid_at": 1565512168, "dispute": null, "refunds": null, "order": null, "outcome": null, "visual_codes": {}, "textual_codes": {}, "instructions": [], "ewallet_id": null, "ewallets": [], "payment_method_options": {}, "payment_method_type": "us_mastercard_card", "payment_method_type_category": "card", "fx_rate": 0, "merchant_requested_currency": null, "merchant_requested_amount": null, "payment_fees": null, "invoice": "", "escrow": null } }
Note
If the intent is to create a different payment with a different currency and a different payment method, you cannot use the same idempotency
header value when the amount is the same.