API Documentation




  1. User visits your online store and makes a purchase. The user decides to pay via ML ePay.
  2. Your website contacts ML ePay through an API call via HTTP POST to create a transaction. The ML ePay API responds with a unique transaction code.
  3. Your website gives the transaction code to the user along with instructions to present the code when making the payment at any M Lhuillier branch.
  4. User goes to an M Lhuillier branch, presents the code, and completes the payment for the transaction.
  5. Once M Lhuillier has received the payment, ML ePay will send an HTTP POST request with the status of the transaction to the Webhook URL you provided.
  6. Later on, you can request to receive your funds at an M Lhuillier branch or have it transferred to your BPI or BDO bank account.

Creating a Transaction

Sample Request

POST /api/v2/transaction/create HTTP/1.1
Host: www.mlepay.com
Content-Type: application/json
X-Signature: NsYbDGyaztNu3hVMFAFG6qQAkgJ+ivkml4aH0uZxUSg=
Cache-Control: no-cache

{"receiver_email":"merchant@example.com", "sender_email":"test@example.com", "sender_name":"Juan dela Cruz", "sender_phone":"+6390000000", "sender_address":"Blk 1 Lot 2, Sitio Doon, Katabi ng Daan, Pilipinas", "amount":100000, "currency":"PHP", "nonce":"a1s2d3f4g5h6j7k8", "timestamp":1234567890, "payload":"id-91288481772412", "expiry":1371734086, "description":"White Denim Tee Shirt - Female - Small"}
Request Endpoint (HTTP POST Method)

POST to the following URL to create a transaction.
Note: "Content-Type" Header should also be set to "application/json".
Request Body

The transaction details should be in JSON format and placed as the "body" of the HTTP POST request.
request_body = {
   "receiver_email": "your merchant email goes here",
   "sender_email": "customer email goes here",
   "sender_name": "customer name goes here",
   "sender_phone": "customer contact goes here",
   "sender_address": "customer address goes here",
   "amount": amount goes here,
   "currency": "PHP",
   "nonce": "unique nonce goes here",
   "timestamp": UNIX timestamp,
   "expiry": UNIX timestamp,
   "payload": "your custom payload goes here",
   "description": "transaction description goes here"
Note: The "amount" is the value in centavos and formatted as an integer. For example: PHP 1,000.00 would be indicated as 100000.
Parameters and Options

Parameter Description
String. The receiver email is your merchant email, this is unique to every account and is provided in the Merchant Profile page.
String. The email address of the customer or buyer.
String. The name of the customer or buyer.
String. The mobile or landline phone number of the customer or buyer.
String. The address of the customer or buyer.
Integer. The amount in centavos to be paid by the customer or buyer.
String. The currency of the transaction. Currently, only "PHP" is supported.
String. A random unique 16-character string to identify this request. This is used as a security measure.
Integer. The UNIX Timestamp of the current date and time. This is used as a security measure.
Integer. The UNIX Timestamp of the date and time the transaction is set to expire. This is useful for transactions with a set "deadline" or "cutoff" for payments to be completed.
String. Custom transaction details. When the status of a transaction is changed, the payload will also be passed along with the other transaction details as a notification to the webhook. This will NOT be shown to the customer or buyer.
String. The description of the transaction. This will be shown to the buyer or customer.
Generating the Signature

1. Generate the Signature Base String

  1. Convert the HTTP Method to uppercase and set the output string equal to this value.
  2. Append the '&' character to the output string.
  3. Percent encode the URL and append it to the output string.
  4. Append the '&' character to the output string.
  5. Percent encode the parameter string and append it to the output string.

The steps would look something similar to the following:
base_string = "POST"
base_string += "&" + urllib.quote("https://www.mlepay.com/api/v2/transaction/create")
base_string += "&" + urllib.quote(request_body)

The content of base string would look like the following:

2. Calculate the Signature

The signature is calculated by passing the SECRET KEY and the BASE STRING to the HMAC-SHA256 function and encoding the result into BASE64:
signature = base64.b64encode(hmac.new(secret_key, base_string, hashlib.sha256).digest()).decode()

3. Place the calculated SIGNATURE in the request header using the "X-Signature" label.
header = {"X-Signature": signature}

Sending the Request

1. Send the HTTP POST request with all the data.
url = "https://www.mlepay.com/api/v2/transaction/create"
response = HTTPPostRequest(url, request_body, headers)
Example POST preview
POST /api/v2/transaction/create HTTP/1.1
Host: https://www.mlepay.com
Content-Type: application/json
X-Signature: 8odbOS75B3bbycj6ua6qCcpFXQnxPxfCE3NepZc9LAA=
Cache-Control: no-cache

POST Request Body:
{"receiver_email":"merchant@example.com", "sender_email":"test@example.com", "sender_name":"Juan dela Cruz", "sender_phone":"+6390000000", "sender_address":"Blk 1 Lot 2, Sitio Doon, Katabi ng Daan, Pilipinas", "amount":100000, "currency":"PHP", "nonce":"a1s2d3f4g5h6j7k8", "timestamp":1234567890 "payload":"id-91288481772412", "expiry":1371734086, "description":"White Denim Tee Shirt - Female - Small"}

2. If the request succeeds, the response will contain the transaction code, among other meta data. Give the returned transaction code to the customer. The customer will need the transaction code in order to make the payment at an M Lhuillier branch. If the transaction creation failed and an error is returned, please see our commmon error recovery tactics further below.

Successful Response
   "description": "Transaction Generated.",
   "transaction": {
      "amount": 10000,
      "payload": "your_custom_payload",
      "code": "EPAY-A1S2D3F4G5H6",
      "currency": "PHP",
   "code": 200,
   "content": {},
   "response": "SUCCESS"
Note: You should save the Transaction Code and give a copy to your buyer. They will need to present the Transaction Code to an M Lhuillier branch in order to complete the payment for your transaction.

Error Responses
Name Code Recovery Tactics* Note
IncorrectSignature 460 B Ensure that the request signature is generated with HMAC-SHA256 and that the secret key being used is the right one.
MerchantDoesNotExist 404 C The server cannot find the merchant account.
MissingRequestHeaders 406 B Ensure that all the required headers for the request are set.
InvalidPayload 406 B JSON dump the payload/body of the request. Also make sure that you Content-Type is set to 'aplication/json'.
UnableToProcess 401 C or D if it still persist The merchant account may be in an unapproved or frozen state.
CannotGenerateTransactionCode 462 A The server cannot generate a transaction code for the request at the moment.
RequiredParameterMissing 463 B The HTTP POST data has lacking required parameters. This would be a good time to double check spelling.
InvalidAmountValue 463 B The amount value should be positive in centavos without a decimal point. All transactions with negative "amount" value are rejected and returned with an error.
ExpiredTransaction 463 B The transaction request timestamp has exceeded the 24-hour limit.
Error 500 D A server-side error occured. Contact us at help@mlepay.com if the error persists after several retries.

* Error Recovery Tactics
Here are some common tactics on recovering from an error:

A. Retry the operation.
The request may have timed out.

B. Double check required parameters and spelling.
Check if all the required parameters are correctly set. Check spelling.

C. You may have to wait until your account is approved/unfrozen by ML.
Transactions from accounts set to unapproved or frozen will not be processed.

D. Contact ML ePay or send a ticket.
This tactic may be useful when experiencing a server-side error.

Notification Webhooks

In order to notify you of events and status changes of your transactions (For example: a customer completing the payment for a transaction at an M Lhuillier branch), ML ePay sends HTTP POST requests to a URL endpoint you can customize in your Merchant Account Profile page.
Sample Notification

Complete Request:
POST /webhook HTTP/1.1
Host: www.your-site.com
Content-Type: application/json
X-Signature: 8odbOS75B3bbycj6ua6qCcpFXQnxPxfCE3NepZc9LBA=
Cache-Control: no-cache

{"receiver_email": "merchant@example.com", transaction_code": "EPAY-ASDFGHJKL2P1", "transaction_status": "PAID", "sender_email": "test@example.com", "sender_name": "Juan dela Cruz", "sender_phone": "+6390000000", "sender_address": "Blk 1 Lot 2, Sitio Doon, Katabi ng Daan, Pilipinas", "amount": 100000, "currency": "PHP", "expiry": 1371734086, "timestamp": 1371734065 "nonce": "a2s3d4f5g6h7j8k9" "payload": "id-91288481772412", "description": "White Denim Tee Shirt - Female - Small"}

Notification Parameters

Parameter Description
String. The merchant email of the owner of this transaction.
String. The Transaction Code of the Transaction this notification is about.
String. The current status of the transaction.
String. The name of the buyer or customer.
String. The email address of the buyer or customer.
String. The phone number of the customer or buyer.
String. The address of the customer or buyer.
Integer. The amount in centavos paid (or to be paid) by the customer or buyer.
String. The currency of the transaction. Currently, only "PHP" is supported.
Integer or None. The UNIX Timestamp of the date and time the transaction was set to expire, if set.
Integer. The UNIX Timestamp of the current date and time. This is used as a security measure.
String. A random unique 16-character string to identify this request. This is used as a security measure.
String. Custom transaction details not shown to the customer. This was passed when the transaction was created.
String. The description of the transaction. This was shown to the buyer or customer.
Notification Types

Type Description
The Transaction has already been paid by the customer or buyer.
The Transaction has expired without payment.
This Transaction has been created.
The Transaction has been cancelled without payment.
Verifying the Notification

ML ePay uses the same process to calculate the signature of its requests. So in order to verify the request from ML ePay, you just need to recalculate the signature for the request, and compare it with the X-Signature given in the request header.

Verify using the following steps:

  1. Check if the timestamp is within a valid period (24 hours), otherwise reject the notification.
  2. Check the nonce has not been previously used within the past 24 hours, otherwise reject the notification.
  3. Calculate the signature:
    • Generate the signature base string for the request.
    • IMPORTANT: The base string uses the request destination url. Therefore, you should use your webhook full url, instead of the mlepay url, in generating the base string.
    • Pass the signature base string along with your SECRET KEY to an HMAC-SHA256 function.
    • Encode the result into a base64 format.
    • Compare the signature you calculated with the signature given in the "X-Signature" header. If it matches, the notification is verified, otherwise the notification is unverified and you must reject it.
Note: You may "silently" reject unverified notifications by returning a 200 HTTP status code, but it would be a good practice to log and investigate these unverified notifications. If you notice any suspicious activity, don't hesitate to contact us.

4. Check if the resulting signature is the same as the one given in the X-Signature header.
5. If it's the same, the notification is verified. Otherwise, it's unverified and should be rejected.

Your Response

If you received a verified request, you must acknowledge it with 200 HTTP Status Code.

Note: ML ePay will resend notifications that didn't receive a 200 status code response. The first few retries will happen immediately after the initial failure. However, subsequent retries will have more and more time between them. Retrying will be stopped after 4 days.

Testing the API

Creating Test Transactions

Creating Test Transactions are quite simple. Just use any email address at example.com as your "sender_email" and the API will automatically treat it as a test transaction that is NOT stored. Examples of test email addresses are the following:


Note: Standard email notifications normally sent out from ML ePay to the buyer or customer will be sent to your merchant email address when test transactions are created.

Simulate Notifications

Login You must log in to use the Notification Simulator Tool.