Overview
Introduction
You can use your Easy Process merchant account to receive payments. This document gives instructions on how to integrate a simple payment button and the postback data that will be sent to your server.
System Overview
Easy Process is a payment system that allows you to do quick, efficient and secure online transaction processing using credit/debit cards.
With your Easy Process control panel, you are able to overview your transactions and manage your account.
Definitions
- merchant: Refers to the merchant of Easy Process who is processing transactions for its customers.
- customer: Refers to the party attempting to process a transaction.
- request: Every call to the Easy Process system will generate a request, identified by a unique ID.
- transaction: A transaction is an act of payment. It is always associated to a request.
- gateway: Refer to the Easy Process payment page on which the customer will be redirected when he clicks on the Payment Button.
Request VS Transaction
In the Easy Process system, every call to the system will generate a request, identified by a unique ID. This ID must be used as a reference to communicate with Easy Process.
On the other hand, a transaction is a reference to a payment. So, every transaction is associated to a request, but a request has not necessarily a transaction associated. For example, if a request is rejected because of some invalid parameters, no transaction will be created.
This is why it is very important to always refer to the request id, rather than the transaction id.
Payment Button Integration
Interface Location
All the requests should go to the following URL:
| Sandbox | Production |
|---|---|
| https://gateway.idem-club.info/idem/ | https://gateway.idem-club.com/idem/ |
Testing
At the beginning of the integration process, a test account will be provided on a sandbox. You will be plugged on the live/production environment only after several successful tests.
The sandbox URL is: https://easyprocess.info/merchants/
In order to proceed a successful payment on the sandbox, you must use the following card information:
- Card number: 4444333322221111
- Validity: 05/28
- CVV: 235
A Quick Start
For the payment button to work you must create a form using the POST method and all the parameters you send should use hidden fields. Here is an example:
<form action="https://gateway.idem-club.info/idem/" method="post">
<input type="hidden" name="merchant_id" value="12345678" />
<input type="hidden" name="amount" value="5.00" />
<input type="hidden" name="currency" value="USD" />
<input type="hidden" name="order_ref" value="1234" />
<input type="hidden" name="user[email]" value="[email protected]" />
<input type="hidden" name="user[firstname]" value="John" />
<input type="hidden" name="user[lastname]" value="Doe" />
<input type="hidden" name="user[zipcode]" value="33301" />
<input type="hidden" name="user[city]" value="Fort Lauderdale" />
<input type="hidden" name="user[country]" value="US" />
<input type="hidden" name="hash" value="..." />
<input type="hidden" name="order_description" value="Order #1234" />
<button type="submit">Pay</button>
</form>
The example above is the shortest version of the payment button that you can use. The item name is "Order number 1234" and its price is 5.00. The payment will go to your account if you replace 12345678 above with your Easy Process Merchant ID.
Easy Process offers many more options that you can send in this form. Please see the list of parameters below for advanced usage.
Parameters list
Below you can see an explanation of all the parameters that can be used for payment buttons:
| Parameter Name | Required | Description |
|---|---|---|
| merchant_id | YES | Your 8 digits Easy Process Merchant ID |
| amount | YES | The total amount requested |
| currency | YES | The currency of the transaction (always the same currency as your Easy Process Merchant Account). |
| order_ref | YES | A unique reference for this transaction |
| order_description | NO | The transaction description (will be echoed to the customer) |
| sub_account_id | NO | An optional sub account ID to group your transactions |
| hash | NO | Checksum of the request (see chapter 5) |
| user[email] | YES | Customer's email address |
| user[firstname] | YES | Customer's first name |
| user[lastname] | YES | Customer's last name |
| user[address] | NO | Customer's address |
| user[zipcode] | YES | Customer's postal code |
| user[city] | YES | Customer's city |
| user[country] | YES | Customer's country |
| user[state] | NO | Customer's state (for US resident only) |
| user[cellphone] | NO | Customer's cell phone (with international prefix) |
| completed_url | NO | The URL where the user will be redirected to after he completes the payment. On the last step of the payment there is a button labeled "Return" and when the user clicks this button he is redirected to this URL. If provided, this parameter override the value set in your settings (see chapter 3.3). |
| cancelled_url | NO | The URL where the user will be redirected to after he cancels the payment. On the cancel step of the payment there is a button labeled "Return" and when the user clicks this button he is redirected to this URL. If provided, this parameter override the value set in your settings (see chapter 3.3). |
| rejected_url | NO | The URL where the user will be redirected to after the payment has been rejected. On the rejection page of the payment there is a button labeled "Return" and when the user clicks this button he is redirected to this URL. If provided, this parameter override the value set in your settings (see chapter 3.3). |
Additional parameters for recurring payments
If you want your payment to be followed by recurring payments, you can provide these additional parameters in your request.
| Parameter Name | Required | Description |
|---|---|---|
| recurring[enabled] | NO | Enable recurring payment/subscription. Must be set to 'yes' in order to enable recurring payment. |
| recurring[amount] | NO | The total amount requested for all recurring payments. |
| recurring[cycles] | NO | Number of cycles/periods (>1 or 0 for unlimited) |
| recurring[periodicity] | NO | Recurring period (weeks, months, years) |
| recurring[start date] | NO | Date of the first (next) transaction (format is YYYY-MM-DD) |
| recurring[hash] | NO | Checksum of the recurring request (see chapter 5) |
Here is a quick example for a payment followed by recurring payments:
<form action="https://gateway.idem-club.info/idem/" method="post">
<input type="hidden" name="merchant_id" value="12345678" />
<input type="hidden" name="amount" value="5.00" />
<input type="hidden" name="currency" value="USD" />
<input type="hidden" name="order_ref" value="1234" />
<input type="hidden" name="hash" value="..." />
<input type="hidden" name="order_description" value="Subscription #1234" />
<input type="hidden" name="user[email]" value="[email protected]" />
<input type="hidden" name="user[firstname]" value="John" />
<input type="hidden" name="user[lastname]" value="Doe" />
<input type="hidden" name="user[zipcode]" value="33301" />
<input type="hidden" name="user[city]" value="Fort Lauderdale" />
<input type="hidden" name="user[country]" value="US" />
<input type="hidden" name="user[state]" value="FL" />
<input type="hidden" name="recurring[enabled]" value="yes" />
<input type="hidden" name="recurring[amount]" value="10.00" />
<input type="hidden" name="recurring[cycles]" value="12" />
<input type="hidden" name="recurring[periodicity]" value="months" />
<input type="hidden" name="recurring[start_date]" value="2024-07-20" />
<input type="hidden" name="recurring[hash]" value="..." />
<button type="submit">Pay</button>
</form>
In this example, the customer will make an initial payment of 5.00 USD, and on July 20, 2024, they will be charged 10.00 USD, and so on for 12 months.
Global settings
You can define some global settings of the payment page in your Easy Process account. Once logged, go into "Account Settings".
Customization
Here you can personalize the name and URL of your website, and you can also provide the logo of your website/company, as an URL. We heavily recommend using an https URL for the logo in order to avoid a security warning from the browser.
Customer Support
After a payment, and in the emails that we send to the customer, we always include a way to contact our customer support. If you prefer to use your own customer support, you can set your own info here.
Return URLs
The default URLs where the user will be redirected to after payment, if not provided in the request parameters. On the last step of the payment there is a button labeled "Return" and when the user clicks this button he is redirected to this URL.
Meaning of these URLs:
- success: when payment has been accepted
- cancelled: when the customer has cancelled the payment by himself
- rejected: when the payment has been rejected
- pending: when the payment is pending for manual action (signature or verification)
Automatic notifications
You can specify an URL and an email address on which you want to receive automatic notifications when the status of your transaction is updated.
Please see the IPN section for more details on Instant Payment Notifications.
Hash key
The hash key is used to calculate the hash tag, you can define your hash key here and choose if Easy Process must check the hash tag for all incoming request from you.
Please see the Hash sum/Checksum section for more details.
JavaScript SDK
Introduction
The JavaScript SDK provides an easy way to integrate G-Standard payment processing directly into your web application. With just a few lines of code, you can create secure payment forms that handle card processing, 3D Secure authentication, and real-time status updates.
Prerequisites
Contact your sales representative to enable the SDK for your account.
Configuration
Step 1: Enable SDK in Settings
Go to your merchant settings and configure the SDK:
- Secret key (
sk_…): generated by the platform, shown masked in your settings. It stays on your server and is the only key that can create a payment session. Never put it in a page. - Publishable key (
pk_…): generated by the platform, shown in your settings. It goes in your page and can only submit a card on a session your server created. - Allowed Origins: the exact origins of the pages that host the form, scheme and host, port if any (e.g.,
https://yoursite.com,https://www.yoursite.com). Mandatory: without it every card submission is refused (origin_not_configured).
Both keys are generated together by your account manager; ask them to regenerate the pair if the secret key ever reaches a page or a repository. Make sure to note your Merchant ID (an 8-digit number), as you will need it in the server call and in the page.
Quick Start
Step 1: Create the payment session on your server
Your server opens the payment session with your secret key. The amount, the currency, your order reference and the customer are set here, once, and the browser cannot change them. The response carries a session_id that you hand to your page.
Please take a look at the example, on the right or below if you're on mobile.
Create the payment session (server side, with the secret key)
curl -X POST https://www.easyprocess.ai/api/sdk/payment/session \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"merchant_id": "12345678",
"amount": 49.99,
"currency": "USD",
"order_ref": "1234",
"customer": {
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"address": "1 Main Street",
"city": "New York",
"state": "NY",
"zipcode": "10001",
"country": "US",
"phone": "+13055550123"
}
}'
<?php
// Same call from PHP. $secretKey comes from your configuration, never from a page.
$ch = curl_init('https://www.easyprocess.ai/api/sdk/payment/session');
curl_setopt_array($ch, array(
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $secretKey,
'Content-Type: application/json'
),
CURLOPT_POSTFIELDS => json_encode(array(
'merchant_id' => '12345678',
'amount' => 49.99,
'currency' => 'USD',
'order_ref' => '1234',
'customer' => array(
'email' => '[email protected]', 'firstname' => 'John', 'lastname' => 'Doe',
'address' => '1 Main Street', 'city' => 'New York', 'state' => 'NY',
'zipcode' => '10001', 'country' => 'US', 'phone' => '+13055550123'
)
))
));
$session = json_decode(curl_exec($ch), true);
curl_close($ch);
if (empty($session['success'])) {
// $session['code'] and $session['message'] say why (see Error Codes): stop here
throw new RuntimeException('Payment session refused: ' . (isset($session['code']) ? $session['code'] : 'no response'));
}
$sessionId = $session['session_id']; // hand it to your page (Step 3)
The response: {"success": true, "session_id": "…", "expires_at": "…", "status": "active", "attempts": 0, "reused": false}. The session lives 30 minutes and is tied to order_ref (25 characters maximum): calling again for the same order returns the same session ("reused": true) with its current status; the same order with another amount or currency is refused (order_ref_conflict). The customer fields are the ones of the card payment. Email, first name, last name, city and country are mandatory, and the state is mandatory for a US customer. A session without them is refused at payment time (invalid_customer). Send the address and the zip code too: the platform does not test them, but they go to the anti-fraud checks. An IDEM Club merchant also needs a mobile number, for a customer that IDEM Club does not know yet. A customer sent from the page is ignored.
All the dates that the platform sends you are in the Eastern time of the United States (America/New_York), and expires_at is one of them. This zone is EST in winter and EDT in summer, and the dates carry no timezone suffix. Read them with that zone, never with a fixed offset: a fixed offset is wrong for half of the year.
The session_id is a secret. Whoever holds it, together with your publishable key, can submit a card on that session and read its outcome. Do not log it, do not put it in a URL, do not show it to your support staff. Pass it to your page in the HTML you render, or through your own authenticated endpoint.
Step 2: Basic HTML Setup
Please look at the example on the right or below if you're on mobile.
Basic HTML Setup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Page</title>
<!-- SDK Files (use the correct domain for your environment) -->
<!-- Prod: https://www.easyprocess.ai | Sandbox: https://www.easyprocess.info -->
<script src="https://www.easyprocess.ai/sdk/v1/sdk.min.js"></script>
<!-- Minimal styling for the SDK -->
<link rel="stylesheet" href="https://www.easyprocess.ai/sdk/v1/sdk.min.css">
<!-- Optional: Your custom styles -->
<style>
#payment-container {
max-width: 400px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
</style>
</head>
<body>
<div id="payment-container">
<h2>Complete Payment</h2>
<div id="payment-form"></div>
</div>
<script>
// Your JavaScript goes here (see next section)
</script>
</body>
</html>
JavaScript Implementation
Please look at the example on the right or below if you're on mobile.
JavaScript Implementation
// Initialize the SDK with the PUBLISHABLE key (environment is inferred from the domain serving the SDK)
var sdk = PaymentSDK.init({
merchantId: '12345678', // Replace with your merchant ID
publishableKey: 'pk_YOUR_PUBLISHABLE_KEY' // The pk_ key. Never the sk_ key.
});
// Create the payment form on the session your server created in Step 1
var paymentForm = sdk.createPaymentForm({
container: '#payment-form',
sessionId: 'SESSION_ID_FROM_YOUR_SERVER', // the session_id of Step 1
// Success handler
onSuccess: function(result) {
console.log('Payment successful, transaction', result.transaction_id);
alert('Payment completed! Transaction ID: ' + result.transaction_id);
// Redirect to success page
window.location.href = '/payment-success';
},
// Error handler
onError: function(error) {
console.error('Payment failed:', error.code, error.message);
alert('Payment failed: ' + error.message);
},
// Pending handler (for async processors)
onPending: function(context) {
console.log('Processing payment...');
// SDK automatically handles status updates via SSE
// The form will update when payment completes
}
});
When the customer clicks Pay, the SDK reads the state of the session first and sends the card only when the session is still open: a page reloaded on a paid order shows the outcome and calls onSuccess without sending a card again.
Testing
Sandbox Environment
- Load SDK from the sandbox domain:
https://www.easyprocess.info/sdk/v1/sdk.min.js - Create the session with the secret key of your sandbox account, on
https://www.easyprocess.info/api/sdk/payment/session: sandbox and production have their own pair of keys - Test cards for synchronous processors:
- Success:
4444333322221111 - Decline: Any other valid card number
- Success:
- Test cards for async processors:
- Success:
4242424242424242, or any other valid card number - Decline: An async processor decides on the amount, not on the card. Ask your account manager for the amounts of your sandbox processor.
- Success:
- CAUTION: the SDK does a Luhn test in the browser, before it sends the card. A card that fails this test never reaches the processor, whatever your sandbox accepts.
Browser Console
- Open Developer Tools (F12)
- Check Console for any errors
- Verify SDK initialization message
Common Test Scenarios
- Successful payment
- Declined card
- Invalid card number
- Expired card
- Missing required fields
Production Checklist
- [ ] Load SDK from production domain (
https://www.easyprocess.ai) - [ ] Verify CORS origins are correctly configured
- [ ] Keep the secret key on your server: the page holds the publishable key only
- [ ] Test with real payment amounts
- [ ] Implement proper error handling
- [ ] Add logging for troubleshooting
- [ ] Set up webhook endpoints for backend processing
Advanced Features
Debug Logging
Use the optional onLog function to surface SDK internal logs to your console:
Please look at the example on the right or below if you're on mobile.
Debug Logging
var sdk = PaymentSDK.init({
merchantId: '12345678',
publishableKey: 'pk_YOUR_PUBLISHABLE_KEY',
onLog: function() {
// Prefix logs for easy filtering in the console
try {
console.log('[PaymentSDK]', Array.prototype.slice.call(arguments));
} catch (e) {}
}
});
What gets logged:
- SDK initialization details (version, merchant id, domain-inferred environment)
- SSE connection events (open, message, error)
- Status updates received from the stream
- Non-fatal parse or network errors
Handle Async Payments
Please look at the example on the right or below if you're on mobile.
Handle Async Payments
onPending: function(context) {
// Show custom loading UI
document.getElementById('loading-message').style.display = 'block';
// context.session_id names the session: keep it for your own logic, never log it
// SSE automatically handles updates
// onSuccess or onError will be called when complete
}
Webhook Integration
Do not rely on JavaScript callbacks alone for fulfillment or accounting. Always implement a backend Webhook listener to receive authoritative status updates even if the browser closes or the network drops.
- What it is: Server-to-server notification on status changes (completed, rejected, refunded, etc.)
- Why it matters: More reliable than browser redirects; ensures consistent backend updates
- What to do: Expose a secure endpoint that validates the message and finalizes your order on terminal status
- Learn more: See the IPN section in this documentation
Error Codes
| Code | Description | User Action |
|---|---|---|
declined |
Payment was declined by the card processor (counts one of the 3 requests the session may send to the processor) | Try different payment method |
invalid_request |
Request refused before the processor (missing or invalid parameter). No attempt consumed | Check the parameters and submit again |
invalid_customer |
A mandatory customer field is empty: first name, last name, city, country, or the state for a US customer. No attempt consumed | Complete the customer object |
invalid_email |
Customer email address rejected (invalid, or not accepted by the platform). No attempt consumed | Correct the email address |
amount_out_of_range |
Amount below the minimum or above the maximum of your account. No attempt consumed | Check the amount limits of your account |
currency_mismatch |
Currency differs from your account currency. No attempt consumed | Use your account currency |
duplicate_reference |
A payment with this order reference was already received (HTTP 409). No attempt consumed | Check the status of that order and payment before retrying; use a new reference only for a genuinely new purchase |
order_ref_conflict |
An open session exists for this order reference with another amount or currency (HTTP 409) | Reconcile with the open session (same amount and currency) or let it expire; a new reference is only for a different order |
payment_refused |
Request refused after its creation but before the processor (customer account or card locked, processor unavailable on this channel). No attempt consumed | Follow the message |
payment_in_progress |
Another submission of this order is being processed right now (HTTP 409); the SDK reads the order's outcome and follows it | Do not resubmit |
session_busy |
Another request is opening the session of this order (HTTP 409) | Retry in a moment |
session_inactive |
The session's payment is in flight or already completed (HTTP 409); the SDK reads the outcome and follows it | Do not resubmit |
payments_unavailable |
Payments are suspended on this merchant account (HTTP 403) | Contact support |
forbidden_new_users |
Your account accepts known customers only, and this email has no account yet (HTTP 403). No attempt consumed | Contact support |
idem_signup_not_allowed |
Your account is an IDEM Club account, but it does not allow automatic login or signup (HTTP 422). No attempt consumed | Contact support |
merchant_not_found |
The merchant of the server call does not exist (HTTP 404). No attempt consumed | Check the merchant_id of your server call |
processing_error |
The platform did not complete the payment (HTTP 500). This response does not say what happened to the card | Read the status of the session before you submit again |
attempts_exceeded |
Three requests already reached the processor on this session (the session counts declined, pending and completed requests; it restarts from zero when the platform switches the order to the fallback processor) | Wait and try again later |
unauthorized |
No Authorization header (HTTP 401) |
Pass the publishable key to PaymentSDK.init(); send the secret key on payment/session |
secret_key_invalid |
The key sent to POST /api/sdk/payment/session is not the secret key of this merchant (HTTP 401). A publishable key is refused here too |
Check the secret key and the merchant_id of your server call |
public_key_invalid |
The key in the page is not the publishable key of the merchant that owns the session (HTTP 401) | Check the publishable key passed to PaymentSDK.init(), and that the session was created for the same merchant |
secret_key_in_browser |
A secret key (sk_) was sent from the page (HTTP 403). The platform logs it as a leak |
Remove the secret key from the page, use the publishable key, and ask for both keys to be regenerated |
origin_required |
A browser endpoint was called without an Origin header (HTTP 403). Browsers send it on cross-origin requests only: the page must be served from one of your allowed origins, not from the platform host |
Call payment/process, payment/status and payment/stream from the page only; your server calls payment/session |
origin_not_configured |
No allowed origin is configured on your account (HTTP 403) | Set the allowed origins in your settings |
origin_not_allowed |
The origin of the page is not in your allowed origins (HTTP 403) | Add the exact origin (scheme and host, port if any) to the allowed origins |
not_found / method_not_allowed |
Unknown endpoint, or wrong HTTP method (HTTP 404 / 405) | Check the SDK version and the URL |
session_expired |
Payment session expired | Refresh page and start over |
Troubleshooting
| Issue | Solution |
|---|---|
| "Missing Authorization header" | Pass the publishable key to PaymentSDK.init(); on payment/session, send Authorization: Bearer sk_… |
| "Invalid secret key" on payment/session | Check the secret key and the merchant_id; sandbox and production keys differ |
| "A secret key was presented on a browser endpoint" | The page holds the secret key: remove it, use the publishable key, ask for both keys to be regenerated |
| "Origin not allowed" / "No allowed origin is configured" | Add the exact origin of your page to the allowed origins in your settings |
| "Session expired" | Payment took too long, refresh page |
| "SDK disabled" | Contact support to enable SDK |
| Form doesn't appear | Check container selector exists |
| SSE connection fails | Ensure CloudFlare or similar is not blocking SSE |
Debugging a refused session or payment
If POST /api/sdk/payment/session answers 401 or 403, or if the form shows an error before any card is sent:
- Enable logging - Initialize with
onLogto capture SDK messages - Verify domain/environment - Ensure correct domain (sandbox:
.biz, prod:.com); the keys of one environment do not work on the other - Inspect Network tab - Every response carries
code,messageandcorrelation_id - Common causes:
secret_key_invalid: wrong secret key, or wrongmerchant_idin the server callpublic_key_invalid: wrong publishable key in the page, or a session of another merchantsecret_key_in_browser: the secret key ended up in the pagesdk_disabled_merchant: the SDK is not enabled on your accountorigin_not_allowed/origin_not_configured: the exact origin of the page is not in your allowed originssession_not_found/session_expired: the page holds a stalesession_id; create a new session
- Provide
correlation_idto support for faster tracing
IPN (Instant Payment Notification)
Definitions
Instant Payment Notification (IPN) is a message service that notifies you of events related to Easy Process transactions. You can use it to automate back-office and administrative functions, such as fulfilling orders, tracking customers, and providing status and other information related to a transaction.
IPN notifies you when an event occurs that affects a transaction. Typically, these events represent various kinds of payments; however, the events may also represent authorizations, fraud management actions and other actions, such as refunds, disputes, and chargebacks.
IPN is a message service that Easy Process uses to notify you about events. These events include the following:
- Payments
- Refunds
- Rejected request/transaction
In many cases, the action that causes the event, such as a payment, occurs on your website; however, your website is not the only source of events. In many cases, events can be generated by the Easy Process Gateway, an Easy Process agent or by the customer themself.
You detect and process IPN messages with a listener, sometimes called a handler, which is a script or program that you write, on your side. It waits for messages and passes them to various back-end or administrative processes that respond the messages.
The actions to take when your listener is notified of an event are specific to your needs. Examples of the kinds of actions you might take when your listener receives an IPN message include the following:
- Trigger order fulfillment or enable media downloads when a check clears or a payment is made
- Update your list of customers
- Update accounting records
- Create specialized "to do" lists based on the kind of event
You will "always" receive the IPN, no matter what the customer does after the transaction. This way IPN enables you to automate your response to events.
When I will receive what and where?
The most frequently asked question when a merchant integrates Easy Process Payment Button is "When and where I will receive the IPN?".
The answer is "For the 'where', it depends on your global settings and for the 'when', IPN is sent automatically on all status change.".
The IPN is sent automatically on the URL specified in your settings (this cannot be overridden in the request), when the status of your transaction is updated (it can be accepted, rejected, refunded or chargeback).
Please note that there is no IPN for pending or cancelled transaction. In case of cancellation, the customer will simply be redirected to the URL you provided.
It is important to understand that the IPN is a server-to-server communication, and that it does not require an action made by the customer, and it cannot be altered. This way, the IPN is more reliable than the simple "return on website".
We encourage you to use the IPN in order to process automatically the transactions and to not trust the "return URL" alone.
Also note that, most of the time, your will receive the IPN before the customer returns to your website, but, in rare case, due to network latency, you may encounter a short delay.
Data sent in the IPN
This data is sent in a POST "array".
In PHP, for example, you will access these data using $_POST['MerchantApiResponse'].
For a better understanding, we can represent these data as an HTML form, like the one below.
<form method="post">
<input type="hidden" name="MerchantApiResponse[status]" value="OK">
<input type="hidden" name="MerchantApiResponse[request_id]" value="11122">
<input type="hidden" name="MerchantApiResponse[request_status]" value="completed">
<input type="hidden" name="MerchantApiResponse[tr_id]" value="22782">
<input type="hidden" name="MerchantApiResponse[sub_account_id]" value="8888">
<input type="hidden" name="MerchantApiResponse[ref_id]" value="1234">
<input type="hidden" name="MerchantApiResponse[msg]" value="">
<input type="hidden" name="MerchantApiResponse[info]" value="">
<input type="hidden" name="MerchantApiResponse[phone_number]" value="[email protected]">
<input type="hidden" name="MerchantApiResponse[w_number]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][request_id]" value="11122">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][tr_id]" value="22782">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][user_id]" value="6095">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][ref_id]" value="1234">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][sub_account_id]" value="8888">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][date]" value="2024-03-27 13:19:35">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][refund_date]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][expiration]" value="2024-03-28 01:19:35">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][statement_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][refund_statement_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][method]" value="gateway">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][currency]" value="USD">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_amount]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_origin]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_amount]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_origin]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_origin]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_origin]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_origin]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][security_origin]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformReason[Location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformReason[Location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformReason[Location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformReason[Location_id]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][card_bin]" value="440393">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][card_last4]" value="5167">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][card_brand]" value="VISA">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][card_type]" value="debit">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][card_country]" value="US">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][customer_routing]" value="credit">
<input type="hidden" name="MerchantApiResponse[PlatformRequest][customer_routing_reason]" value="fallback_direct">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_to_type]" value="merchant">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_to_id]" value="12345678">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_to_currenty]" value="USD">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_requested_original]" value="5.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_requested_currenty]" value="USD">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_amount_requested]" value="5.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_amount_transfered]" value="5.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_amount_total_cost]" value="5.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_amount_refunded]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_change_rate]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_fees]" value="0.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_fees_cure]" value="USD">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_fees_type]" value="fixed">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_fees_rate_fixed]" value="0.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_fees_rate_percent]" value="0.0000">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_fees_level]" value="2">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_date_created]" value="2024-03-27 13:19:35">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_date_updated]" value="2024-03-27 13:19:42">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_date_completed]" value="2024-03-27 13:19:42">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_date_refunded]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_notif_sender]" value="email">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_notif_receiver]" value="none">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_status]" value="completed">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][tr_status_msg]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformTransaction][ray_infos]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="John">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="Joe">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="John">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="Joe">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="Joe">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="Joe">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][mainname]" value="Joe">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][subress]" value="Some street">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][subress]" value="Some street">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][subress]" value="Some street">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][subress]" value="Some street">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question1]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question1]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question2]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question2]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question3]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question3]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question4]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question2]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question2]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question3]" value="">
<input type="hidden" name="MerchantApiResponse[PlatformAccount][question3]" value="">
<input type="hidden" name="MerchantApiResponse[hash]" value="def2e614513fc7cf0d85c97167fb10ab">
</form>
MerchantApiResponse
Below are all the parameters of the post back and IPN explained
Root data
| Properties | Type | Description |
|---|---|---|
| status | string | Has the value "OK" for successful, "PENDING" for pending transaction or "ERROR" for failure |
| request_id | int | Request ID is the unique ID of the request |
| request_status | string | Request status, it can be 'pending', 'accepted', 'rejected', 'cancelled', 'completed', 'refunded' |
| tr_id | int | Transaction ID is the unique ID of transaction associated to the request |
| sub_account_id | string | Sub Account ID for which you have associated this request |
| ref_id | string | Reference ID is the unique ID you've passed for this request |
| msg | string | Message |
| info | string | Additional information |
| PlatformTransaction | object | Easy Process Transaction information associated to a request/transaction |
| PlatformAccount | object | Easy Process Account information associated to a request/transaction |
| PlatformRequest | object | Easy Process Request with full information |
| hash | string | Hash code to check the authenticity of the IPN response |
PlatformTransactionType
| Properties | Type | Description |
|---|---|---|
| tr_id | int | Internal unique ID in the Easy Process system for this transaction |
| tr_type | string | Transaction type. |
| tr_from_type | string | Transaction source type. |
| tr_from_id | string | Transaction source id. |
| tr_from_curric | string | The main currency of the source account |
| tr_to_type | string | Transaction destination type. Usually "merchant" |
| tr_to_id | string | Transaction destination id. |
| tr_to_curric | string | Transaction destination currency. |
| tr_requested_original | float | Transaction original requested amount |
| tr_requested_curric | string | Transaction original requested currency |
| tr_amount_requested | float | Transaction converted requested amount (used currency is defined in $tr_from_Currency) |
| tr_amount_transfered | float | Transaction converted transferred amount (used currency is defined in $tr_to_Currency) |
| tr_amount_total_cost | float | Transaction total cost including fees (used currency is defined in $tr_from_Currency) |
| tr_amount_refunded | float | Transaction refunded amount (used currency is defined in $tr_from_Currency) |
| tr_change_rate | float | Transaction change rate from $tr_requested_curric and the $tr_from_Currency if not the same |
| tr_fees | float | Transaction fees that generally apply to the sender $tr_from_id) |
| tr_fees_curric | string | Transaction fees currency (generally the same as $tr_from_Currency) |
| tr_fees_type | string | Type of fees ('fixed', 'percent', both') |
| tr_fees_rate_fixed | float | Fixed part of the fees |
| tr_fees_rate_percent | float | Variable part of the fees |
| tr_fees_level | int | User level applied to the fees and limits |
| tr_date_created | string | Transaction creation date |
| tr_date_updated | string | Transaction last update |
| tr_date_completed | string | Transaction processing date |
| tr_date_refunded | string | Transaction refund date |
| tr_notif_sender | string | Type of notification sent to the sender |
| tr_notif_receiver | string | Type of notification sent to the receiver |
| tr_status | string | Transaction status ('waiting', 'rejected', 'played', 'refunded', 'loaded', 'confirmed', 'completed', 'cancelled') |
| tr_status_msg | string | Transaction status additional information |
PlatformAccountType
| Properties | Type | Mandatory | Description |
|---|---|---|---|
| user_id | int | Internal unique ID in the Easy Process system | |
| currency | string | Mallet currency. | |
| string | Yes, if no cellphone | Email address - UNIQUE per customer. | |
| gender | string | Gender: 'M' for Male / 'F' for Female. | |
| firstname | string | Yes | First name |
| middlename | string | Middle name | |
| lastname | string | Yes | Last name |
| address | string | Yes | Address |
| city | string | Yes | City |
| zipcode | string | Yes | Zip/Postal code |
| country | string | Yes | Country code (2 chars) |
| state | string | Yes, for US | State code (2 chars / for US citizen only) |
| phone | string | Phone number. Used for contact purpose only. | |
| birthday | string | Birthday. Format: YYYY-MM-DD | |
| question1 | int | First security question (cf. documentation for possible values). | |
| answer1 | string | Answer for the first security question (max 60 chars). | |
| question2 | int | Second security question (cf. documentation for possible values). | |
| answer2 | string | Answer for the second security question (max 60 chars). | |
| question3 | int | Third security question (cf. documentation for possible values). | |
| answer3 | string | Answer for the third security question (max 60 chars). |
PlatformRequestType
| Properties | Type | Description |
|---|---|---|
| request_id | integer | Internal unique ID in the Easy Process system for this request |
| tr_id | integer | Internal unique ID in the Easy Process system for the associated transaction |
| user_id | integer | Internal unique ID of a customer in the Easy Process system |
| ref_id | string | Your reference ID |
| sub_account_id | string | Sub Account ID |
| date | string | Date of the request (format: YYYY-MM-DD HH:MM:SS) |
| refund_date | string | Refund date of the request (format: YYYY-MM-DD HH:MM:SS) |
| expiration | string | Expiration date (format: YYYY-MM-DD HH:MM:SS) |
| statement_id | integer | Statement ID (if transaction has been settled to the merchant) |
| refund_statement_id | integer | Refund statement ID (if transaction has been refunded on a statement) |
| method | string | Request method (api, gateway, terminal) |
| is_recurring | boolean | True if the request has been initiated as a recurring transaction |
| is_a_cycle | boolean | True if the request is part of a recurring cycle |
| recurring_id | integer | Main/parent recurring request ID (filled if $is_a_cycle is true) |
| type | string | Transaction type. Possible values are: "credit card" |
| currency | string | Request currency |
| amount | float | Original requested amount or Initial amount for recurring request |
| description | string | Description |
| addinfo | string | Additional info that you have provided |
| status | string | Request status |
| status_infos | string | Additional info's on the status |
| recurring_amount | float | Recurring amount |
| recurring_cycles | integer | Number of recurring cycles |
| recurring_period | string | Recurring period ('weeks', 'months', 'years') |
| recurring_start | string | Recurring payment start date (format: YYYY-MM-DD HH:MM:SS) |
| recurring_end | string | Recurring payment end date (format: YYYY-MM-DD HH:MM:SS) |
| recurring_status | string | Recurring status. Possible values are: "pending", "open", "stopped", "terminated" |
| decline_cause | string | Stable, machine-readable cause code for failed payments (added 2026-08-11) — safe to branch on, unlike the human-readable rejection message. Present on failure statuses only, never on success. Values: a debit-rail cause (not-valid, prepaid, foreign-issuer, credit, refused-by-rail, unconfirmed), no-response (technical failure, not a card refusal), or the card processor's own response code (e.g. 300) |
| card_bin | string | First 6 digits of the stored card number (added 2026-08-26). Null on non-card payments, or when the stored value is not a plain 12–19 digit card number (masked entries are never used to derive a BIN) |
| card_last4 | string | Last 4 digits of the stored card number. Null when card_bin is null |
| card_brand | string | Card scheme from our card reference data, uppercase: VISA, MASTERCARD, DISCOVER, AMEX, … Null when card_bin is null or the BIN is not in our reference data |
| card_type | string | debit or credit, from our card reference data. Null when card_bin is null or our reference data has no type for this BIN. Describes the number on record, not a verified physical card — the debit rail performs its own account-level checks, and decline_cause carries the rail's verdict |
| card_country | string | Issuing country, ISO 3166-1 alpha-2 (US, MX, …). Null when card_bin is null or our reference data has no country for this BIN |
| customer_routing | string | The card rail our customer-level routing rules would select for this customer right now: debit (the processor configured in your debit-card slot) or credit (another, credit-card processor). Computed when the notification is generated, before card-level rules and availability checks. Null when no customer is attached to the request, card processing is not enabled on your account, or no card processor is configured |
| customer_routing_reason | string | Why this route was selected: default (no debit-only rule applies), dc_only_unverified (customer has not met the graduation criteria — identity not verified and no completed, non-refunded payment older than 5 days anywhere on our platform), dc_loop (graduated, but a successful debit-rail history keeps them on the debit rail), fallback_direct (successful debit-rail history and your account sends returning debit customers directly to your credit-card processor), dc_only_all (your account routes every customer to the debit rail). Do not derive "unlocked for credit card" from the graduation rule alone: a graduated customer can still be debit (dc_loop) |
| transaction | object | Associated transaction |
Hash sum / Checksum
Purpose
A checksum or hash sum is a small-size datum computed from an arbitrary block of digital data for the purpose of detecting errors or modifications that may have been introduced during its transmission. To secure your payments, Easy Process offers 2 different checksums:
- one for the Payment Button request: you will have to calculate this hash and send it into your Payment Button.
- Another one in the IPN: you will have to calculate it, and to compare with the one provided in the response.
Even if it is not mandatory to calculate and verify the checksums, Easy Process heavily encourages you to use them.
Key and settings
In order to have and to calculate the checksum, you must first define a hash key in your settings (see chapter 3.5). This hash key is like a password and must never be communicated in clear text.
Please use only alphanumeric characters in your key, special characters may produce invalid hashes.
For the Payment Button requests, if you want that Easy Process checks your hash, you must activate this function in your settings (see chapter 3.5). If this setting is not set to « Yes », Easy Process will ignore the « hash » parameter, even if it is present.
Formula for the « Hash » in the Payment Button request
Single payment (or initial payment for subscription)
The calculation of the Payment Button hash requires only 5 parameters. The hash can be found by a md5sum of a string formed by concatenating the following variables (in the given order and without any other characters or spaces):
- merchant_id
- amount
- currency
- order_ref
- your private key
For example, in PHP, you will use the following code:
$hash_key = 'yourhashkey';
$hash = md5($merchant_id.$amount.$currency.$order_ref.$hash_key);
Once calculated, this hash should be placed in the 'hash' parameter.
<input type="hidden" name="hash" value="<?php echo $hash; ?>" />
Recurring payment / Subscription
In addition to the « single payment» hash above, if you want to make a recurring payment, you've to calculate a second hash with the parameters specific to this subscription. This specific hash can be found with the same method but with these parameters instead:
- recurring amount
- cycles
- periodicity
- start_date
- your private key
For example, in PHP, you will use the following code:
$hash_key = 'yourhashkey';
$hash = md5($recurring['amount'].$recurring['cycles'].$recurring['periodicity'].$recurring['start_date'].$hash_key);
Once calculated, this hash should be placed in the 'recurring[hash]' parameter.
<input type="hidden" name="recurring[hash]" value="<?php echo $hash; ?>" />
Formula for the « Hash » in the IPN
The hash is present in the root of the MerchantApiResponse ($_POST['MerchantApiResponse']['hash'] using PHP)
The calculation of this hash requires only 5 parameters.
The hash can be found by a md5sum of a string formed by concatenating the following variables (in the given order and without any other characters or spaces):
- request_id
- amount
- currency
- status
- your private key
For example, in PHP, you will use the following code:
$mykey = 'yourprivatekey-notyourpassword!';
$request = $_POST['MerchantApiResponse']['PlatformRequest'];
$myhash = md5($request['request_id'].$request['amount'].$request['currency'].$request['status'].$mykey);
if ($myhash == $_POST['MerchantApiResponse']['hash']) echo "The request is valid";
Code Samples
HTML
The example below is the more complete version of the payment button that you can use, with all possible parameters.
<form action="https://gateway.idem-club.info/idem/" method="post">
<input type="hidden" name="merchant_id" value="12345678" />
<input type="hidden" name="amount" value="5.00" />
<input type="hidden" name="currency" value="USD" />
<input type="hidden" name="order_ref" value="1234" />
<input type="hidden" name="sub_account_id" value="8888" />
<input type="hidden" name="order_description" value="Order number 1234" />
<input type="hidden" name="hash" value="" />
<input type="hidden" name="user[email]" value="[email protected]" />
<input type="hidden" name="user[firstname]" value="John" />
<input type="hidden" name="user[lastname]" value="Doe" />
<input type="hidden" name="user[address]" value="200 SW 1st Avenue" />
<input type="hidden" name="user[zipcode]" value="33301" />
<input type="hidden" name="user[city]" value="Fort Lauderdale" />
<input type="hidden" name="user[country]" value="US" />
<input type="hidden" name="user[state]" value="FL" />
<input type="hidden" name="user[cellphone]" value="" />
<input type="hidden" name="completed_url" value="https://demo.easyprocess.info/return/success/" />
<input type="hidden" name="cancelled_url" value="https://demo.easyprocess.info/return/cancelled/" />
<input type="hidden" name="rejected_url" value="https://demo.easyprocess.info/return/rejected/" />
<input type="submit" name="submit" value="Pay with Easy Process" />
</form>
Special Notes
Mandatory fields for customer account on the gateway
Due to regulation laws, the customer must provide his first name, last name, address (city, zipcode, country and state for US customer) and his email address.
Restrictions
- PO Boxes are not allowed. Transaction created with such address will be rejected.
- Limits like "no more than 3 transactions of the same kind in one day, and 5 in one week, 10 in the month" can apply depending of your agreement.
Recurring payment / Subscription
If you propose subscriptions on your web site, you can use our recurring's payments parameters (see parameters list in earlier sections). For this kind of payment, the initial payment amount can be different than the coming payments. This is useful if you want to provide, for example, a trial period at 50% off, or, a first payment that include additional fees. In order for the recurring payments to take place, the first initial payment must be accepted. It is why, for now, it is not possible to make a free initial payment. Once the recurring payment is running, you will receive IPN for every payment, and you will have options in your account to cancel it. To see these options, you will have to find the initial request ID in your transactions.
Control panel
The administrative merchant front end of Easy Process is located at: https://easyprocess.ai/merchants (https://easyprocess.info/merchants for the sandbox) Just sign in with the merchant details you have obtained from us. The main features are:
- Transaction monitoring
- Refunding transactions
- Viewing transaction details
Disclaimer
(c) 2022 - 2025 Easy Process. All rights reserved.
Easy Process and the authors assume no liability for errors or omissions, or for damages, resulting from the use of this guide or the information contained in this guide.