API v1FiatPe Home
FiatPeDocs
SERVER 2 SERVER

S2S EMI

Initiate card EMI payments from your server using an issuer and tenure returned by the Methods API.

Supported EMI plans

Fetch the issuer-specific EMI tenures and percentage rates available to your account using the Methods API.

The emi_plans object contains issuer codes and their available plans. Each plan key is the tenure in months, and its value is the percentage rate charged for that plan. Offer only a returned tenure and send it as emi_duration.

Open the Methods API guide
STEP 1

Create the order on your server

Create a new FiatPe order for each payment attempt. Amounts use the smallest currency sub-unit: for INR, 5000 represents ₹50.00. Store the returned order ID against your internal order before using it in the S2S payment request.

Open the Create Order API reference

Server request example

Use your FiatPe credentials only from a trusted backend environment.

REQUEST

Curl
Copy
curl --request POST \
  --url https://api.fiatpe.com/v1/orders/ \
  --header "Authorization: Basic YOUR_BASE64_CREDENTIALS" \
  --header "Content-Type: application/json" \
  --data '{
    "amount": 5000,
    "currency": "INR"
  }'

Response

Store the returned data.id and pass it as the order_id in Step 2.

200 OK
Copy
{
  "data": {
    "id": "order_2f40f08f4baa4e5b",
    "amount": 5000,
    "entity": "order",
    "status": "created",
    "currency": "INR",
    "metadata": {},
    "created_at": 1788148983,
    "return_url": null,
    "amount_paid": 0,
    "bank_details": null,
    "return_method": "POST",
    "amount_pending": 5000
  },
  "message": "order created successfully."
}
STEP 2

Initiate an EMI payment

Send the request from your backend with the card details and the EMI tenure selected from the Methods API response. Generate the Basic authorization value by Base64 encoding api_key:secret_key.

REQUEST

Curl
Copy
curl --location 'https://api.fiatpe.com/v1/payments/s2s/' \
  --header 'Authorization: Basic <base64(api_key:secret_key)>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "amount": 5000,
    "currency": "INR",
    "contact": "+919898989898",
    "name": "Aftab Hussain",
    "email": "customer@example.com",
    "order_id": "order_2129fc063f6a4e0b",
    "return_url": "https://example.com/payment/return",
    "callback_url": "https://api.example.com/webhooks/fiatpe",
    "description": "Test payment",
    "method": "emi",
    "emi_duration": 9,
    "card": {
      "number": "4242424242424242",
      "name": "Aftab",
      "expiry_month": 11,
      "expiry_year": 30,
      "cvv": 100
    },
    "metadata": {
      "note_key": "value1"
    }
  }'

Request fields

FieldRequiredDescription
amountYesPayment amount in the currency’s smallest sub-unit.
currencyYesThree-letter currency code, such as INR.
contactYesCustomer phone number including the country code.
nameYesCustomer’s full name.
emailYesCustomer email address.
order_idYesOrder ID returned in Step 1.
return_urlYesHTTPS URL used after card authentication completes.
callback_urlNoOptional HTTPS endpoint on your server where FiatPe sends asynchronous payment updates.
descriptionNoDescription associated with the payment.
methodYesSet to emi.
emi_durationYesSelected EMI tenure in months. Use a plans object key returned for the card issuer in emi_plans; its corresponding value is the percentage rate charged.
card.numberYesCustomer’s card number. Handle it only in a PCI DSS-compliant environment.
card.nameYesName printed on the card.
card.expiry_monthYesCard expiry month.
card.expiry_yearYesCard expiry year.
card.cvvYesCard verification value. Never store or log it.
metadataNoMerchant-defined key-value data associated with the payment.

Handle the response action

EMI payments use the same authentication response actions as S2S card payments. Always inspect next[].action instead of assuming a fixed response flow.

Test every response flow in UAT before going live.

Your integration must successfully handle Native, Redirect, and HTML Form flows in the UAT environment. The flow returned for a transaction can vary based on the configured TID, acquiring bank, issuing bank, payment network, payment method, and other transaction parameters.

Do not hardcode a flow for a card, bank, wallet, or PayLater provider. Always inspect the returned next[].action value and process otp_submit, resend_otp, redirect, or html_form as instructed by the API response.

Native OTP response

200 OK
Copy
{
  "payment_id": "FIATPESTCM3YWO15VB1790705241",
  "next": [
    {
      "action": "otp_submit",
      "url": "https://api.fiatpe.com/v1/payments/FIATPESTCM3YWO15VB1790705241/otp/submit/"
    },
    {
      "action": "resend_otp",
      "url": "https://api.fiatpe.com/v1/payments/FIATPESTCM3YWO15VB1790705241/otp/resend/"
    }
  ]
}

Redirect response

200 OK
Copy
{
  "payment_id": "FIATPESTK1CU1FNRXR1790705821",
  "next": [
    {
      "action": "redirect",
      "url": "https://api.fiatpe.com/v1/payments/FIATPESTK1CU1FNRXR1790705821/authentication/"
    }
  ]
}

HTML Form response

200 OK
Copy
{
  "payment_id": "FIATPEST8OJ7CDB2BI1790705845",
  "next": [
    {
      "action": "html_form",
      "html_content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Redirecting | FiatPe</title>\n  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js\"></script>\n</head>\n<body>\n  <div class=\"redirect-container\">\n    <div id=\"lottie-loader\"></div>\n    <h1>Redirecting...</h1>\n    <p>Please wait while we redirect you securely. Do not close this window.</p>\n    <form id=\"payment-form\" method=\"GET\"\n      action=\"https://api.fiatpe.com/v1/payments/FIATPEST8OJ7CDB2BI1790705845/authentication/\"\n      hidden>\n      <input type=\"hidden\" name=\"paymentMode\" value=\"CARD\">\n    </form>\n    <noscript>\n      <button type=\"submit\" form=\"payment-form\">Continue to payment</button>\n    </noscript>\n  </div>\n  <script>\n    if (window.lottie) {\n      lottie.loadAnimation({\n        container: document.getElementById(\"lottie-loader\"),\n        renderer: \"svg\",\n        loop: true,\n        autoplay: true,\n        path: \"https://bucket.fiatpe.com/static/animation/lottie/fiatpe_pg_processing_loader.json\"\n      });\n    }\n    window.setTimeout(function () {\n      document.getElementById(\"payment-form\").submit();\n    }, 1000);\n  </script>\n</body>\n</html>"
    }
  ]
}

Complete and verify the EMI payment

  • For otp_submit or resend_otp, use the action URLs returned for that payment.
  • For redirect, navigate the customer’s browser to the returned URL.
  • For html_form, render the returned HTML as a complete browser document.
  • Do not store or log the CVV, OTP, full card number, or API secret.
  • Confirm the final payment status and selected EMI tenure on your backend before fulfilment.