Extra Amount

Introduction

This guide walks you through integrating Extra Amount via EdfaPay’s Server-to-Server (S2S) Card Payment using the SALE action. This feature allows partners to charge additional fees in a transaction, which remain with the partner while the merchant receives only the original amount..


Endpoint

POST https://api.edfapay.com/payment/post

Content-Type: multipart/form-data

❗️

Security Note

All API requests must be sent over HTTPS to ensure data integrity and confidentiality.


Request Parameters

FieldTypeRequiredDescription
actionStringYesTransaction type. Use "SALE" for standard sale transactions.
client_keyStringYesYour unique merchant identifier issued by EdfaPay.
order_idStringYesUnique identifier for the transaction/order.
order_amountDecimalYesAmount to be charged (e.g., 0.11).
order_currencyStringYesCurrency code in ISO 4217 format (e.g., SAR).
order_descriptionStringYesDescription of the order.
req_tokenStringOptional"Y" to request a tokenized transaction; "N" otherwise.
payer_first_nameStringYesFirst name of the customer.
payer_last_nameStringYesLast name of the customer.
payer_addressStringYesThe email or address of the customer.
payer_countryStringYesCountry code (ISO 3166-1 alpha-2), e.g., "SA".
payer_cityStringYesCity of the payer.
payer_zipStringYesZIP or postal code of the payer. Max length: 5 digits.
payer_emailStringYesThe email address of the customer.
payer_phoneStringYesThe customer’s phone number with country code.
payer_ipStringYesIP address of the customer. Must follow the format of IPv4. Example: XXX.XXX.XXX.XXX
term_url_3dsStringYesURL that the customer is redirected to after completing 3D Secure authentication.
authStringOptional"Y" to authorize only, "N" for authorize + capture (default).
recurring_initStringOptional"Y" if this transaction is a recurring initiation.
hashStringYesSecure hash for request authentication.
extrasArray jsonOptionalExtra charges for the transaction. Each object contains type ("AMOUNT"), name (fee description), and value (amount).
card_numberStringYesCustomer's card number (PAN).
card_exp_monthStringYesExpiry month in MM format.
card_exp_yearStringYesExpiry year in YYYY format.
card_cvv2StringYesCVV/CVC of the card.
🚧

For order_id

Must be unique per transaction. Duplicate order_id may result in rejected or duplicated payments.

👍

payer_ip:

Ensure IP address is captured accurately for fraud prevention and 3D Secure validation.

📘

recurring_init and req_token:

Use "Y" only if initiating tokenization or recurring billing. These options are required for saved cards or subscriptions

📘

extras:

extras is partner-only; merchant payout is without extras.

type must be "AMOUNT" and value is in transaction currency.

Hash Generation (Request Authentication)

To secure your API request, you must generate a hash using the request data and your secret merchant password. This hash ensures that the request is authentic and hasn’t been tampered with.

Formula

var password = "XXXXXXXXXXXXXX";
var cardNumber = "XXXXXXXXXXXXXXXX";
var email = "[email protected]";

const ReverseString = str => [...str].reverse().join('');

var final = (ReverseString(email) + password + ReverseString(cardNumber.substr(0, 6) + cardNumber.substr(-4))).toUpperCase();
var finalHash = CryptoJS.MD5(final).toString();
❗️

Common Mistakes

Make sure to reverse the email and card segments correctly. Any mismatch between hash calculation on your side and our validation will cause the request to fail.


Notes:

  • password → Your secret hash key from EdfaPay.
  • cardNumber → The full card number entered by the customer.
  • email → The customer’s email used in hash generation.

Example cURL Request

curl --location 'https://api.edfapay.com/payment/post' \
--form 'action="SALE"' \
--form 'client_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"' \
--form 'payer_first_name="Test"' \
--form 'payer_last_name="Test"' \
--form 'payer_phone="+966577293572"' \
--form 'payer_city="Riyadh"' \
--form 'payer_country="SA"' \
--form 'payer_email="[email protected]"' \
--form 'payer_address="some address"' \
--form 'order_id="EXTRA_TEST-S2S-20251016-0006"' \
--form 'order_amount="100"' \
--form 'order_currency="SAR"' \
--form 'card_number="5123450000000008"' \
--form 'card_exp_month="01"' \
--form 'card_exp_year="2039"' \
--form 'card_cvv2="100"' \
--form 'payer_zip="12345"' \
--form 'payer_ip="176.44.76.222"' \
--form 'auth="N"' \
--form 'order_description="Test Order with Extras"' \
--form 'term_url_3ds="https://www.success.com"' \
--form 'hash="GENERATED_HASH"' \
--form 'recurring_init="N"' \
--form 'req_token="N"' \
--form 'extras="[
  {\"type\":\"AMOUNT\",\"name\":\"WhatsApp Reminder\",\"value\":10},
  {\"type\":\"AMOUNT\",\"name\":\"Refund Guarantee\",\"value\":12}
]"'
❗️

Important Note — Hash Generation

The hash parameter included in the request body is dynamically generated for each request and must not be hardcoded.

The hash value is calculated using specific request parameters combined with your merchant secret key. Any change in the request data requires regenerating the hash before sending the request.

🔗 For detailed steps and the exact formula used to generate the hash, refer to the Hash Generation Section.


Successful Response

{
  "action": "SALE",
  "result": "REDIRECT",
  "status": "REDIRECT",
  "order_id": "EXTRA_TEST-S2S-20251016-0006",
  "trans_id": "XXXXXXXXXXXXXXXXXXXXXXXXX",
  "trans_date": "30-12-2025 12:00:00",
  "amount": "100",
  "currency": "SAR",
  "redirect_url": "https://pgapi.edfapay.com/s2s/collector/XXXXXXXXXXXXXXXXXXXXXXXXX",
  "redirect_params": {
    "body": "BASE64_ENCODED_JSON_STRING"
  },
  "redirect_method": "POST",
  "merchant_id": "Merchant_name"
}
  • action: The type of transaction performed (always SALE).
  • result: Indicates what to do next (REDIRECT means further action is needed).
  • status: Current transaction status (also REDIRECT here).
  • order_id: The order ID you sent in the original request.
  • trans_id: Unique transaction ID generated by EdfaPay (also used at the end of the redirect_url).
  • trans_date: The date and time of the transaction.
  • amount: The transaction amount.
  • currency: The currency used (e.g., SAR).
  • redirect_url: The URL to which you should send the next POST request.
  • redirect_params.body: Base64-encoded data to include in the POST request body.
  • redirect_method: HTTP method to use for the redirect (always POST).
  • merchant_id: Merchant Name.

Redirect to Collector

POST https://pgapi.edfapay.com/s2s/collector/{trans_id}

Content-Type: application/json

{
  "body": "BASE64_ENCODED_JSON_STRING"
}

Use the value from redirect_params.body received in the response on the Successful Response of the Sale API

📘

Important Notes

The body must be sent exactly as received from redirect_params.body. It is Base64-encoded JSON that the collector uses to complete the transaction.

The total charged to the customer = order_amount + sum(extras). Merchant payout = order_amount only.


Response

This request will return an HTML page (3DS challenge, OTP, etc.) which must be rendered to the user. You can open this in:

  • A browser (web integration)
  • A WebView (mobile apps)
Language
Click Try It! to start a request and see the response here!