GLODIPAY IFRAME CARD API SPECIFICATION
VERSION 2.0.0
Table of Contents
- Introduction
- Endpoints
- Signature
- POST PAYMENT
- TRANSACTION QUERY
- NOTIFICATION
- Simulating Payments
Use the Test environment. No real charges are made.
| Without 3DS | 4111 1111 1111 1111 | 01/30 | 029 | — |
| Without 3DS | 5555 5555 5555 4444 | 01/30 | 029 | — |
| 3DS Payment | 4012 8888 8888 1881 | 01/30 | 029 | Success: 123456 / Fail: 111111 |
| 3DS Payment | 5111 1111 1111 1118 | 01/30 | 029 | Success: 123456 / Fail: 111111 |
| 3DS Payment | 4141 4141 4141 4141 | 12/30 | 123 | Success: 123456 / Fail: 111111 |
- Appendix
- Status Values
- Status Codes
- Currency Codes
- Country Codes
- Card Types
- Code Examples
- PHP
- Node.js
Introduction
This document describes the GLODIPAY iFrame Card API v2, which allows merchants to embed GLODIPAY's hosted card input form inside their own web page using an HTML <iframe>.
Flow overview:
- Merchant server sends a POST request to
/v2/card/iframeto create a card session. - GLODIPAY returns a signed, temporary URL pointing to a hosted card input form.
- Merchant embeds this URL inside an
<iframe>on their checkout page. - Buyer enters card details on the GLODIPAY-hosted form within the iframe.
- GLODIPAY processes the payment and sends the result via IPN to
notificationUrl, then redirects the buyer tocallbackUrlorerrorUrl.
The merchant's page maintains its layout while GLODIPAY handles the card data securely. The card session URL expires at the time specified by expiresAt (default: 24 hours).
Endpoints
| Test | Get it from the API Keys page of the Sandbox Merchant Dashboard |
| Production | Get it from the API Keys page of the Merchant Dashboard |
Signature
All requests and responses are signed using RSA with MD5 to ensure integrity and authenticity.
Generating a Signature (Merchant -> GLODIPAY)
Sign request payloads with your RSA Private Key (obtained from the Merchant Dashboard).
Steps:
- Collect all request parameters except
signatureas a flat key-value object. - Sort the keys in natural ascending order (
SORT_NATURAL/localeComparewithnumeric: true). - Trim whitespace from all string values (recursive).
- Serialize to JSON string with all non-ASCII Unicode characters escaped to
\uXXXX(RFC 8259). - Sign with
md5WithRSAEncryptionusing your RSA Private Key. - Base64-encode the binary output.
Verifying a Signature (GLODIPAY -> Merchant)
Verify GLODIPAY responses and webhooks with the RSA Public Key (available in the Portal).
Steps:
- Separate
signaturefrom the payload. - Sort remaining keys in natural ascending order.
- Trim all string values (recursive).
- Serialize to JSON string with all non-ASCII Unicode characters escaped to
\uXXXX(RFC 8259). - Verify with
md5WithRSAEncryptionusing your RSA Public Key. - Return value
1= valid.
Note (Node.js): Convert all numeric values to strings before sorting/serializing. Escape forward slashes in the JSON string: .replace(///g, '/').
Note (Unicode / RFC 8259): The JSON payload must escape all non-ASCII Unicode characters (e.g., "a with accent" must become "\u00e1") before signing -- this is required by RFC 8259. In PHP,
json_encode($data)does this by default -- do not useJSON_UNESCAPED_UNICODE. In Node.js,JSON.stringify()does not escape Unicode by default -- apply:.replace(/[^\\x00-\\x7F]/g, c => "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0"))after serializing.
POST PAYMENT
Create a card iframe session. GLODIPAY returns a signed URL to a hosted card input form that the merchant embeds in an <iframe>.
Endpoint: POST /v2/card/iframe
Method: POST
Content-Type: application/x-www-form-urlencoded
Request Parameters
| merchantId | String(1,50) | M | Merchant's ID |
| orderRef | String(1,250) | M | Unique transaction reference per merchant |
| amount | Float | M | Invoice amount. Minimum: 1. Up to 2 decimal places |
| currency | String(3) | M | ISO 4217 currency code. E.g. USD |
| cancelUrl | String(1,300) | M | URL to redirect buyer on cancellation. Must be https |
| callbackUrl | String(1,300) | M | URL to redirect buyer after successful payment. Must be https |
| notificationUrl | String(1,300) | M | Your server endpoint to receive IPN webhooks. Must be https |
| errorUrl | String(1,300) | M | URL to redirect buyer on error. Must be https |
| orderDescription | String(max:3000) | M | Short description of the order |
| metadata | JSON | O | Key-value pairs attached to the session. Returned in IPN and query responses |
| transactionDocuments | JSON | O | Supporting documents for the transaction |
| paymentMethod | String | M | Must be card for iframe card sessions |
| feeBySeller | Number(0-100) | O | Percentage of processing fee paid by merchant. 0 = buyer pays 100%. Up to 2 decimal places |
| billingEmail | String(max:255) | O | Buyer email address |
| billingCountry | String | O | ISO 3166-1 alpha-2 country code |
| billingFirstName | String(max:255) | O | Billing first name |
| billingLastName | String(max:255) | O | Billing last name |
| billingStreet1 | String(max:255) | O | Billing street address line 1 |
| billingStreet2 | String(max:255) | O | Billing street address line 2 |
| billingCity | String(max:255) | O | Billing city |
| billingState | String(2,255) | O | Billing state / province |
| billingPostalCode | String(max:25) | O | Postal / ZIP code |
| billingPhoneCountryCode | String(max:10) | O | Phone country code |
| billingPhoneNumber | String(max:20) | O | Phone number |
| customerIp | String | O | IP address of the customer |
| websiteUrl | String(max:300) | O | Merchant website URL |
| brandName | String(1,255) | O | Override the brand name shown on the card form |
| colorMode | String(1,255) | O | Up to 3 colors separated by ---. E.g. #2e7d32---#e8f5e9---#81c784 |
| logoSource | String(1,255) | O | Override the logo shown on the card form |
| signature | String(max:750) | M | RSA-MD5 signature. See Signature |
| expiresAt | String | O | Session expiry in ISO 8601 format. E.g. 2025-09-14T14:03:42.102862Z. Default: 24 hours |
M = Mandatory, O = Optional
Example Request
{
"merchantId": "1100000123",
"orderRef": "ORDER-001",
"amount": "100.00",
"currency": "USD",
"paymentMethod": "card",
"callbackUrl": "https://yoursite.com/callback",
"notificationUrl": "https://yoursite.com/webhook",
"cancelUrl": "https://yoursite.com/cancel",
"errorUrl": "https://yoursite.com/error",
"orderDescription": "Test order",
"billingFirstName": "John",
"billingLastName": "Doe",
"billingStreet1": "123 Main St",
"billingStreet2": "",
"billingCity": "New York",
"billingEmail": "john@example.com",
"billingState": "NY",
"billingCountry": "US",
"billingPostalCode": "10001",
"billingPhoneCountryCode": "1",
"billingPhoneNumber": "5551234567",
"cardNumber": "4111111111111111",
"cardMonth": "12",
"cardYear": "30",
"cardSecurityCode": "123",
"websiteUrl": "https://yoursite.com",
"signature": "base64-encoded-signature"
}
Response
Content-Type: application/json
| status | String | created |
| transactionId | String (ULID) | GLODIPAY transaction ID |
| url | String | Signed URL to the hosted card input form -- embed this in an <iframe/> |
| message | String | Human-readable message |
Example -- Success:
{
"status": "created",
"transactionId": "01jza90dy6w82dfrrqvadn5vs4",
"url": "https://payment.gpayprocessing.com/v2/card-iframe/01jza90dy6w82dfrrqvadn5vs4?...",
"message": "Iframe card created successfully"
}
Example -- Error:
{
"status": "error",
"transactionId": null,
"url": null,
"message": "No active payment service providers found. Please contact support."
}
Embedding the iFrame
After receiving the url, embed it on your page:
<iframe
src="{url}"
width="100%"
height="600"
frameborder="0"
scrolling="no"
allowtransparency="true">
</iframe>
The url is signed and expires at expiresAt. Do not store or share it beyond the current checkout session. The buyer must complete payment within the session expiry time.
TRANSACTION QUERY
Query the current status and full details of a transaction.
Endpoint: POST /v2/checkout/query
Method: POST
Content-Type: application/json
Request
| transactionId | String (ULID) | M | GLODIPAY transaction ID |
| signature | String(max:750) | M | RSA-MD5 signature |
Response
Content-Type: application/json
| merchantId | String | Merchant's ID |
| transactionId | String | GLODIPAY transaction ID (ULID) |
| transactionNumber | String | GLODIPAY human-readable transaction number |
| ref | String | Merchant's orderRef |
| currency | String | ISO 4217 currency code |
| amount | Float | Invoice amount |
| paidAmount | Float | Amount actually charged to buyer (including buyer fees) |
| settlementAmount | Float | Amount to be settled to merchant |
| estimationSettlementAt | ISO 8601 datetime | Estimated settlement datetime |
| fees | JSON | Fee breakdown. See fees Object |
| status | String | Transaction status. See Status Values |
| statusCode | Number | Numeric status code. See Status Codes |
| metadata | JSON | Key-value pairs from the original session |
| transactionDocuments | JSON | Supporting documents |
| paymentMethodDetails | JSON | Payment method used. See paymentMethodDetails Object |
| message | String | Human-readable status message |
| descriptor | String | Transaction descriptor |
| transactionCreatedAt | ISO 8601 datetime | Transaction creation time in GLODIPAY system |
| originalTransactionCreatedAt | ISO 8601 datetime | Transaction creation time at the PSP |
| signature | String | RSA-MD5 signature -- verify with GLODIPAY public key |
NOTIFICATION
GLODIPAY sends an HTTP POST to your notificationUrl when a transaction reaches a terminal state.
Method: POST
Content-Type: application/json
Retry policy: GLODIPAY may re-send the IPN for transactions that have not been acknowledged. Your server should return {"returnCode":"100"} as soon as the notification is received.
Payload
| merchantId | String | M | Merchant's ID |
| transactionId | String | M | GLODIPAY transaction ID (ULID) |
| transactionNumber | String | M | GLODIPAY human-readable transaction number |
| ref | String | M | Merchant's orderRef |
| currency | String | M | ISO 4217 currency code |
| amount | Float | M | Invoice amount |
| paidAmount | Float | O | Amount actually charged to buyer (including buyer fees) |
| settlementAmount | Float | O | Amount to be settled to merchant |
| estimationSettlementAt | ISO 8601 datetime | O | Estimated settlement datetime |
| fees | JSON | O | Fee breakdown. See fees Object |
| paymentMethodDetails | JSON | O | Payment method used. See paymentMethodDetails Object |
| status | String | M | Transaction status. See Status Values |
| statusCode | Number | M | Numeric status code. See Status Codes |
| metadata | JSON | O | Key-value pairs from the original session |
| transactionDocuments | JSON | O | Supporting documents |
| message | String | O | Human-readable status message |
| descriptor | String | O | Transaction descriptor |
| transactionCreatedAt | ISO 8601 datetime | M | Transaction creation time in GLODIPAY system |
| originalTransactionCreatedAt | ISO 8601 datetime | M | Transaction creation time at the PSP |
| signature | String | M | RSA-MD5 signature -- verify with GLODIPAY public key |
fees Object
| buyer | Float | Buyer-facing fee amount |
| seller | Float | Merchant fee amount |
| rolling | Float | Rolling reserve amount |
| operate | Float | Total operating fees (processor + GLODIPAY + partner) |
| estimationRollingReleaseAt | ISO 8601 datetime | Estimated rolling reserve release datetime |
paymentMethodDetails Object
| displayName | String | Payment method label |
| group | String | Payment method group type |
| family | String | Payment method family type |
| type | String | Payment method type |
{type} | JSON | Optional. Payment method-specific details. Key equals the type value (e.g. card). Only present for card payments when card details are available. See card Object below. |
card Object (paymentMethodDetails.card)
| name | Cardholder name |
| firstSixDigits | First 6 digits of card number (BIN) |
| lastFourDigits | Last 4 digits of card number |
| expiryMonth | Expiry month (MM) |
| expiryYear | Expiry year (YY) |
| type | Card brand (visa, mastercard, amex, etc.) |
| issuer | Issuing bank name (provider-dependent) |
| issuerCountryCode | ISO 3166-1 alpha-2 country code of issuing bank (provider-dependent) |
| funding | Card funding type (credit, debit, prepaid) (provider-dependent) |
| authorizationCode | Authorization code from issuer (provider-dependent) |
| clientIP | Customer IP address at time of payment (provider-dependent) |
| checks | AVS/CVC verification results (provider-dependent) |
| threeDSecure | 3D Secure authentication details (provider-dependent) |
Example IPN Payload:
{
"merchantId": "1100000123",
"transactionId": "01jza90dy6w82dfrrqvadn5vs4",
"transactionNumber": "2604-1713100800",
"ref": "ORDER-001",
"currency": "USD",
"amount": 100.00,
"paidAmount": 105.00,
"settlementAmount": 95.00,
"estimationSettlementAt": "2026-04-16T00:00:00+00:00",
"fees": {
"buyer": 5.00,
"seller": 5.00,
"rolling": 2.00,
"operate": 3.00,
"estimationRollingReleaseAt": "2026-05-14T00:00:00+00:00"
},
"status": "successful",
"statusCode": 6,
"paymentMethodDetails": {
"displayName": "Credit / Debit Card",
"group": "card",
"family": "card",
"type": "card"
},
"metadata": { "orderId": "12345" },
"transactionCreatedAt": "2026-04-14T10:00:00+00:00",
"originalTransactionCreatedAt": "2026-04-14T10:00:01+00:00",
"signature": "base64-encoded-rsa-signature"
}
Response (Merchant -> GLODIPAY)
Your server must respond within 30 seconds:
{
"returnCode": "100",
"description": "Received"
}
| returnCode | String | R | Must be "100" to acknowledge receipt |
| description | String(1,1500) | O | Optional description |
Simulating Payments
Use the Test environment. No real charges are made.
| Without 3DS | 4111 1111 1111 1111 | 01/30 | 029 | — |
| Without 3DS | 5555 5555 5555 4444 | 01/30 | 029 | — |
| 3DS Payment | 4012 8888 8888 1881 | 01/30 | 029 | Success: 123456 / Fail: 111111 |
| 3DS Payment | 5111 1111 1111 1118 | 01/30 | 029 | Success: 123456 / Fail: 111111 |
| 3DS Payment | 4141 4141 4141 4141 | 12/30 | 123 | Success: 123456 / Fail: 111111 |
Appendix
Status Values
String values returned in the status field of IPN payloads and query responses.
| incomplete | Transaction initiated, awaiting action |
| pending | Awaiting payment confirmation |
| under_review | Transaction under review |
| successful | Payment completed successfully |
| failed | Payment failed |
| error | System error occurred |
| canceled | Transaction canceled |
| rejected | Transaction rejected |
| expired | Transaction expired |
| processed | Transaction was submitted to the payment provider |
| released | Funds released / settled |
| documents_uploaded | Supporting documents uploaded |
| refund_initiated | Refund request initiated |
| refund_under_review | Refund under review |
| refund_successful | Refund completed successfully |
| refund_failed | Refund failed |
| refund_partially_successful | Partial refund completed |
| refund_partially_failed | Partial refund failed |
| void_initiated | Void initiated |
| void_under_review | Void under review |
| void_successful | Void completed successfully |
| void_failed | Void failed |
| void_partially_successful | Partial void completed |
| void_partially_failed | Partial void failed |
| chargeback_alert | Chargeback alert received |
| chargebacked | Transaction chargebacked |
| dispute | Dispute opened |
Status Codes
Numeric code in the statusCode field of IPN payloads and query responses.
| 1 | incomplete | Transaction initiated |
| 2 | pending | Pending confirmation |
| 3 | error | System error |
| 4 | failed | Payment failed |
| 5 | under_review | Under review |
| 6 | successful | Payment successful |
| 7 | released | Released / settled |
| 8 | refund_initiated | Refund initiated |
| 9 | refund_failed | Refund failed |
| 10 | refund_under_review | Refund under review |
| 11 | refund_successful | Refund successful |
| 12 | refund_partially_failed | Partial refund failed |
| 13 | refund_partially_successful | Partial refund successful |
| 14 | canceled | Canceled |
| 15 | rejected | Rejected |
| 16 | expired | Expired |
| 17 | documents_uploaded | Documents uploaded |
| 18 | void_initiated | Void initiated |
| 19 | void_under_review | Void under review |
| 20 | void_successful | Void successful |
| 21 | void_failed | Void failed |
| 22 | void_partially_successful | Partial void successful |
| 23 | void_partially_failed | Partial void failed |
| 24 | chargeback_alert | Chargeback alert |
| 25 | chargebacked | Chargebacked |
| 26 | dispute | Dispute opened |
| 27 | processed | Processed |
Currency Codes
GLODIPAY follows the ISO 4217 standard. This endpoint currently accepts USD only.
| USD | United States Dollar |
Country Codes
GLODIPAY uses ISO 3166-1 alpha-2 two-letter codes for billingCountry.
| AD | Andorra |
| AE | United Arab Emirates |
| AF | Afghanistan |
| AG | Antigua and Barbuda |
| AI | Anguilla |
| AL | Albania |
| AM | Armenia |
| AO | Angola |
| AQ | Antarctica |
| AR | Argentina |
| AS | American Samoa |
| AT | Austria |
| AU | Australia |
| AW | Aruba |
| AX | Åland Islands |
| AZ | Azerbaijan |
| BA | Bosnia and Herzegovina |
| BB | Barbados |
| BD | Bangladesh |
| BE | Belgium |
| BF | Burkina Faso |
| BG | Bulgaria |
| BH | Bahrain |
| BI | Burundi |
| BJ | Benin |
| BL | Saint Barthélemy |
| BM | Bermuda |
| BN | Brunei Darussalam |
| BO | Bolivia, Plurinational State of |
| BQ | Bonaire, Sint Eustatius and Saba |
| BR | Brazil |
| BS | Bahamas |
| BT | Bhutan |
| BV | Bouvet Island |
| BW | Botswana |
| BY | Belarus |
| BZ | Belize |
| CA | Canada |
| CC | Cocos (Keeling) Islands |
| CD | Congo, Democratic Republic of the |
| CF | Central African Republic |
| CG | Congo |
| CH | Switzerland |
| CI | Côte d'Ivoire |
| CK | Cook Islands |
| CL | Chile |
| CM | Cameroon |
| CN | China |
| CO | Colombia |
| CR | Costa Rica |
| CU | Cuba |
| CV | Cabo Verde |
| CW | Curaçao |
| CX | Christmas Island |
| CY | Cyprus |
| CZ | Czechia |
| DE | Germany |
| DJ | Djibouti |
| DK | Denmark |
| DM | Dominica |
| DO | Dominican Republic |
| DZ | Algeria |
| EC | Ecuador |
| EE | Estonia |
| EG | Egypt |
| EH | Western Sahara |
| ER | Eritrea |
| ES | Spain |
| ET | Ethiopia |
| FI | Finland |
| FJ | Fiji |
| FK | Falkland Islands (Malvinas) |
| FM | Micronesia, Federated States of |
| FO | Faroe Islands |
| FR | France |
| GA | Gabon |
| GB | United Kingdom of Great Britain and Northern Ireland |
| GD | Grenada |
| GE | Georgia |
| GF | French Guiana |
| GG | Guernsey |
| GH | Ghana |
| GI | Gibraltar |
| GL | Greenland |
| GM | Gambia |
| GN | Guinea |
| GP | Guadeloupe |
| GQ | Equatorial Guinea |
| GR | Greece |
| GS | South Georgia and the South Sandwich Islands |
| GT | Guatemala |
| GU | Guam |
| GW | Guinea-Bissau |
| GY | Guyana |
| HK | Hong Kong |
| HM | Heard Island and McDonald Islands |
| HN | Honduras |
| HR | Croatia |
| HT | Haiti |
| HU | Hungary |
| ID | Indonesia |
| IE | Ireland |
| IL | Israel |
| IM | Isle of Man |
| IN | India |
| IO | British Indian Ocean Territory |
| IQ | Iraq |
| IR | Iran, Islamic Republic of |
| IS | Iceland |
| IT | Italy |
| JE | Jersey |
| JM | Jamaica |
| JO | Jordan |
| JP | Japan |
| KE | Kenya |
| KG | Kyrgyzstan |
| KH | Cambodia |
| KI | Kiribati |
| KM | Comoros |
| KN | Saint Kitts and Nevis |
| KP | Korea, Democratic People's Republic of |
| KR | Korea, Republic of |
| KW | Kuwait |
| KY | Cayman Islands |
| KZ | Kazakhstan |
| LA | Lao People's Democratic Republic |
| LB | Lebanon |
| LC | Saint Lucia |
| LI | Liechtenstein |
| LK | Sri Lanka |
| LR | Liberia |
| LS | Lesotho |
| LT | Lithuania |
| LU | Luxembourg |
| LV | Latvia |
| LY | Libya |
| MA | Morocco |
| MC | Monaco |
| MD | Moldova, Republic of |
| ME | Montenegro |
| MF | Saint Martin (French part) |
| MG | Madagascar |
| MH | Marshall Islands |
| MK | North Macedonia |
| ML | Mali |
| MM | Myanmar |
| MN | Mongolia |
| MO | Macao |
| MP | Northern Mariana Islands |
| MQ | Martinique |
| MR | Mauritania |
| MS | Montserrat |
| MT | Malta |
| MU | Mauritius |
| MV | Maldives |
| MW | Malawi |
| MX | Mexico |
| MY | Malaysia |
| MZ | Mozambique |
| NA | Namibia |
| NC | New Caledonia |
| NE | Niger |
| NF | Norfolk Island |
| NG | Nigeria |
| NI | Nicaragua |
| NL | Netherlands, Kingdom of the |
| NO | Norway |
| NP | Nepal |
| NR | Nauru |
| NU | Niue |
| NZ | New Zealand |
| OM | Oman |
| PA | Panama |
| PE | Peru |
| PF | French Polynesia |
| PG | Papua New Guinea |
| PH | Philippines |
| PK | Pakistan |
| PL | Poland |
| PM | Saint Pierre and Miquelon |
| PN | Pitcairn |
| PR | Puerto Rico |
| PS | Palestine, State of |
| PT | Portugal |
| PW | Palau |
| PY | Paraguay |
| QA | Qatar |
| RE | Réunion |
| RO | Romania |
| RS | Serbia |
| RU | Russian Federation |
| RW | Rwanda |
| SA | Saudi Arabia |
| SB | Solomon Islands |
| SC | Seychelles |
| SD | Sudan |
| SE | Sweden |
| SG | Singapore |
| SH | Saint Helena, Ascension and Tristan da Cunha |
| SI | Slovenia |
| SJ | Svalbard and Jan Mayen |
| SK | Slovakia |
| SL | Sierra Leone |
| SM | San Marino |
| SN | Senegal |
| SO | Somalia |
| SR | Suriname |
| SS | South Sudan |
| ST | Sao Tome and Principe |
| SV | El Salvador |
| SX | Sint Maarten (Dutch part) |
| SY | Syrian Arab Republic |
| SZ | Eswatini |
| TC | Turks and Caicos Islands |
| TD | Chad |
| TF | French Southern Territories |
| TG | Togo |
| TH | Thailand |
| TJ | Tajikistan |
| TK | Tokelau |
| TL | Timor-Leste |
| TM | Turkmenistan |
| TN | Tunisia |
| TO | Tonga |
| TR | Türkiye |
| TT | Trinidad and Tobago |
| TV | Tuvalu |
| TW | Taiwan, Province of China |
| TZ | Tanzania, United Republic of |
| UA | Ukraine |
| UG | Uganda |
| UM | United States Minor Outlying Islands |
| US | United States of America |
| UY | Uruguay |
| UZ | Uzbekistan |
| VA | Holy See |
| VC | Saint Vincent and the Grenadines |
| VE | Venezuela, Bolivarian Republic of |
| VG | Virgin Islands (British) |
| VI | Virgin Islands (U.S.) |
| VN | Viet Nam |
| VU | Vanuatu |
| WF | Wallis and Futuna |
| WS | Samoa |
| YE | Yemen |
| YT | Mayotte |
| ZA | South Africa |
| ZM | Zambia |
| ZW | Zimbabwe |
Card Types
| 1 | VISA | visa |
| 2 | MASTERCARD | mastercard |
| 3 | AMERICAN EXPRESS | amex |
| 4 | JCB | jcb |
| 5 | MAESTRO | maestro |
| 6 | DISCOVER | discover |
| 7 | UNION PAY | union-pay |
| 8 | DINERS | diners |
Code Examples
PHP
<?php
function generateSignature(array $data): string
{
$privateKey = openssl_pkey_get_private("-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----
");
foreach ($data as $k => $v) {
if (is_array($v)) $data[$k] = json_encode($v);
}
ksort($data, SORT_NATURAL);
array_walk_recursive(
$data,
static function (&$field) {
$field = trim($field);
}
);
openssl_sign(json_encode($data), $signature, $privateKey, 'md5WithRSAEncryption');
return base64_encode($signature);
}
// Example: create a v2 card iframe session
$payload = [
'merchantId' => '1100000123',
'orderRef' => 'ORDER-' . time(),
'amount' => '100.00',
'currency' => 'USD',
'paymentMethod' => 'card',
'callbackUrl' => 'https://yoursite.com/payment/callback',
'notificationUrl' => 'https://yoursite.com/payment/webhook',
'cancelUrl' => 'https://yoursite.com/payment/cancel',
'errorUrl' => 'https://yoursite.com/payment/error',
'orderDescription' => 'Test order',
'billingEmail' => 'customer@example.com',
];
$payload['signature'] = generateSignature($payload);
$ch = curl_init('https://payment-sandbox.gpayprocessing.com/v2/card/iframe');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
// Embed $result['url'] in an iframe on your checkout page
echo '<iframe src="' . htmlspecialchars($result['url']) . '" width="100%" height="600" frameborder="0"></iframe>';
Node.js
// Save as script.mjs and run: node script.mjs
import { createSign } from 'crypto';
import https from 'https';
import querystring from 'querystring';
const PRIVATE_KEY = `-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----`;
function phpCast(v) {
if (typeof v === 'number') return String(v);
if (typeof v === 'boolean') return v ? '1' : '';
if (typeof v === 'string') return v.trim();
if (Array.isArray(v)) return v.map(phpCast);
if (v && typeof v === 'object') return Object.fromEntries(Object.entries(v).map(([k, val]) => [k, phpCast(val)]));
return v;
}
function generateSignature(data) {
const sorted = {};
Object.keys(data)
.filter(k => k !== 'signature')
.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }))
.forEach(k => { sorted[k] = data[k]; });
const canonical = JSON.stringify(phpCast(sorted))
.replace(/\//g, '\\/')
.replace(/[\u0080-\uffff]/g, c => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'));
const sign = createSign('md5WithRSAEncryption');
sign.update(canonical);
return sign.sign(PRIVATE_KEY, 'base64');
}
// Example: create a v2 card iframe session
const payload = {
merchantId: '1100000123',
orderRef: 'ORDER-' + Date.now(),
amount: '100.00',
currency: 'USD',
paymentMethod: 'card',
callbackUrl: 'https://yoursite.com/payment/callback',
notificationUrl: 'https://yoursite.com/payment/webhook',
cancelUrl: 'https://yoursite.com/payment/cancel',
errorUrl: 'https://yoursite.com/payment/error',
orderDescription: 'Test order',
billingEmail: 'customer@example.com',
};
payload.signature = generateSignature(payload);
const postData = querystring.stringify(payload);
const options = {
hostname: 'payment-sandbox.gpayprocessing.com',
path: '/v2/card/iframe',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData),
},
};
const req = https.request(options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
const result = JSON.parse(body);
// Embed result.url in an <iframe> on your page
console.log('iFrame URL:', result.url);
});
});
req.on('error', console.error);
req.write(postData);
req.end();