Skip to main content

Maypay APIs - OpenAPI 3.0 (1.0.0)

Download OpenAPI specification:Download

Maypay APIs

Welcome to the Maypay APIs documentation.

Here you can find all the details on how to get access, input parameters and expected results for each individual API exposed by the Maypay service.

Before proceeding to the details of each API, we strongly recommend you read the Authorization section in order to implement the correct API access algorithm

Authorization

Access to the APIs service is protected by an authorisation mechanism based on an API Key. Every merchant wishing to integrate their e-commerce with Maypay must first obtain their own API Key, that consists of a private part that must remain secret and a public part.

To be authorised, the request must contain the following headers:

  • Authorization: MAYPAY <public_key>:<digest>; (mind the semicolon)
  • x-maypay-req-id: random UUID as request identifier.
  • Date: Date string based on rfc7231 date format, to ensure request freshness.

    How to build Authorization header

    As can be seen above, the header consists of 3 distinct fields:
    • MAYPAY: fixed string
    • public_key: the public part of the API Key
    • digest: digitally signed payload of the request using the private part of the API Key

The payload of the request must be a string having the following structure:

<http_method> <url>
<date>
<x-maypay-req-id>
<content-type> (optional)
<json_serialized_body> (optional)       

Here are 2 examples of payloads of a post and a get requests:

POST https://europe-west1-maypay-app.cloudfunctions.net/cancelMerchantPaymentRequest
Mon, 20 Mar 2023 08:34:32 GMT
72f9a80a-5a2c-4200-b719-24399d6f3965
application/json
{"merchantPaymentRequestId":"jA6EqoCld0lYMc55o1gw"}
GET https://europe-west1-maypay-app.cloudfunctions.net/getMerchantPaymentRequest?merchantPaymentRequestId=jA6EqoCld0lYMc55o1gw
Mon, 20 Mar 2023 08:33:51 GMT
dac7b351-c861-49b9-8a55-770608b075e9

After building the string representing the request payload, the digest is obtained by creating a Base64-encoded hash of the payload using the HMAC SHA1 algorithm with the private part of the API Key as secrete key.

Below is an implementation example in NodeJs of how to build headers to access APIs.

const crypto = require("crypto");
const maypayAPIRequest = async (
  method,
  url,
  contentType,
  data,
  publicKey,
  privateKey
) => {
  try {
    let payload, body;

    const headers = {
      "X-MAYPAY-Req-ID": crypto.randomUUID(),
      Date: new Date().toUTCString(),
    };

    payload = `${method} ${url}\n${headers["Date"]}\n${headers["X-MAYPAY-Req-ID"]}`;

    if (contentType === "application/json") {
      headers["Content-Type"] = contentType;
      payload += `\n${headers["Content-Type"]}`;
      if (data) {
        body = JSON.stringify(data)
        payload += `\n${body}`;
      }
    }

    const hm = crypto.createHmac("sha1", privateKey);
    hm.update(payload);
    headers["Authorization"] = `MAYPAY ${publicKey}:${hm.digest().toString("base64")};`;

    const apiResponse = await fetch(url, {
      method,
      headers,
      body,
    });

    const json = await apiResponse.json();
    return json;
  } catch (error) {
    console.log("fetch error", error);
  }
};

Webhooks

How to handle Webhook responses

When creating the payment request, you must provide a callback URL that will act as an endpoint for the communication of the outcome of the transaction.

To ensure security for this communication as well, the request from our servers uses the same authentication mechanism described above.

When the webhook is triggered, you can authenticate the packet by comparing the signature contained in the x-maypay-digest header and the signature created from the packet. The HMAC signature is created using the same API key with which the payment request was created.

Below is an example of how to verify that the signature was created from the same private key written in NodeJS. The req object has the same properties as the Express request object.

const authenticateWebhookResult = (req, privateKey) => {
  try {
    const authorization = req.header("x-maypay-digest");
    const date = req.header("date");
    const contentType = req.header("content-type");
    const xMaypayReqId = req.header("x-maypay-req-id");

    const reg =
      /^MAYPAY\s(maypay_pk_(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})):((?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4}));$/;

    let auth = authorization || "";
    auth = auth.trim();
    const check = auth.match(reg);

    if (!check || check.length <= 2) {
      throw { message: "Invalid Authorization header", code: 401 };
    }

    const pk = check[1];
    const digest = check[2];

    if (!pk || !digest) {
      throw { message: "Missing public key or digest", code: 401 };
    }

    const requestDate = new Date(date).getTime();
    const actualDate = Date.now();

    // Request Freshness
    if (actualDate - requestDate > 5 * 60 * 1000 /* max 5 minutes old*/) {
      throw { message: "Timeout", code: 410 /* GONE */ };
    }

    const hm = crypto.createHmac("sha1", privateKey);
    
    const fullUrl = `${req.headers["x-forwarded-proto"]}://${req.headers.host}${req.url}`;

    let payload = `${req.method} ${fullUrl}\n${date}\n${xMaypayReqId}`;
    payload += "\n" + contentType + "\n" + JSON.stringify(req.body);

    hm.update(payload);

    const compareDigest = hm.digest().toString("base64");
    if (compareDigest !== digest) {
      throw {
        message: "Invalid digest. Received payload: " + payload,
        code: 401,
      };
    }

    console.log("Authorized");
    return true;
  } catch (error) {
    console.error(error);
    return false;
  }
};

Merchant Payment Requests

A payment request represents the willingness of an e-commerce to initiate a payment procedure over the Maypay service.

APIs offer the possibility of:

  • Create a new payment request
  • Cancel an existing and pending one
  • Get the data of a request

Flows

When creating a request you can use one of the following flows:

Flow Use case Payment Flow Create API core parameter Capture Method
Web Button Online - Web Button One-off - Web Button buyerFlowType buyerPhoneNumber(optional) IMMEDIATE
Mobile app Mobile app - Android SDK / Mobile app - iOS SDK One-off - Mobile app redirectUrl IMMEDIATE
Funds Lock - Web button - Funds Lock - Web Button buyerFlowType buyerPhoneNumber(optional) estimatedAmount (optional) MANUAL
Funds Lock - Mobile app - Funds Lock - Web Button redirectUrl estimatedAmount (optional) MANUAL

Create

Authorizations:
API-Key-Digest
header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Request Body schema: application/json

payment request generated after a checkout

amount
required
integer [ 100 .. 50000 ]

Payment amount expressed in cents, i.e. 2.99€ => amount = 299

currency
required
string

ISO 4217 code of payment currency. At the moment the only supported currency is "EUR"

buyerFlowType
required
string
Enum: "phone" "qr" "all"

Mode of interaction to be shown to the user during payment.

  • phone: User must provide his/her phone number, to which a push notification is delivered to confirm the payment via the Maypay app
  • qr: User is shown a qr code that once scanned will open the Maypay app to confirm the payment
  • all: both previous methods
buyerPhoneNumber
string

Buyer's E.164 format Phone Number. Maypay can use this optional field to pre-fill the number in case the need arises.

orderId
required
string

e-commerce internal order ID

callbackUrl
required
string

endpoint used by Maypay to provide payment results. It must be a valid https URL.

storeId
required
string

Maypay store ID

timeout
integer [ 1 .. 60 ]
Default: 5

minutes after which payment is treated as expired

metadata
required
object

ecommerce data for internal use

captureMethod
string
Default: "IMMEDIATE"
Enum: "IMMEDIATE" "MANUAL"

It indicates whether the payment is one-off (IMMEDIATE) or it must be authorized in advance and later captured (MANUAL)

estimatedAmount
integer [ 100 .. 50000 ]

Estimated payment amount expressed in cents, i.e. 2.99€ => 299. It can be used only when captureMethod is equal to MANUAL.

redirectUrl
string

universal link (iOS), app link (Android) of eCommerce application or eCommerce website https url. Used to come back on eCommerce app/website after paying with Maypay app.

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Cancel

Authorizations:
API-Key-Digest
header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Request Body schema: application/json

merchant payment request ID

merchantPaymentRequestId
string

ID of the payment request to be cancelled

Responses

Request samples

Content type
application/json
{
  • "merchantPaymentRequestId": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Get

Authorizations:
API-Key-Digest
query Parameters
merchantPaymentRequestId
required
string
Example: merchantPaymentRequestId=merchantPaymentId

ID of merchant payment request to be fetched

header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Capture

Authorizations:
API-Key-Digest
header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Request Body schema: application/json
merchantPaymentRequestId
required
string

ID of the payment request to be captured

amount
required
integer [ 100 .. 50000 ]

The amount to capture from the pre-authorized amount, which must be less than or equal to the original amount. It is expressed in cents, i.e. 2.99€ => 299

metadata
object

ecommerce data for internal use

Responses

Request samples

Content type
application/json
{
  • "merchantPaymentRequestId": "merchantPaymentRequestId",
  • "amount": 299,
  • "metadata": { }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Create Refund

This api creates a Refund Request object by passing a paymentRequestId or transactionId passed in request body. At least one of these must be specified in the request. Valid values states for refund are REFUNDED, WAITING_REFUND, REFUND_FAILED. The refundedFailureReason response field is returned only if state is REFUND_FAILED.

Authorizations:
API-Key-Digest
header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Request Body schema: application/json
transactionId
string

ID of the transaction to be refunded

paymentRequestId
string

ID of the payment request to be refunded

amount
required
integer [ 100 .. 50000 ]

Amount to be refunded, which must be less than or equal to the original amount. It is expressed in cents, i.e. 2.99€ => 299

Responses

Request samples

Content type
application/json
{
  • "transactionId": "transactionId",
  • "paymentRequestId": "paymentRequestId",
  • "amount": 299
}

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Get Refund

This api returns a Refund Request object by its paymentRequestId or transactionId passed in query parameters. At least one of these must be specified in the request. Valid values states for refund are REFUNDED, WAITING_REFUND, REFUND_FAILED. The refundedFailureReason response field is returned only if state is REFUND_FAILED.

Authorizations:
API-Key-Digest
query Parameters
paymentRequestId
string
Example: paymentRequestId=paymentRequestId

ID of merchant payment request to be refunded

transactionId
string
Example: transactionId=transactionId

ID of transaction to be refunded

header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Store

A Store represents a point of sale of a merchant. The API makes it possible to get information on one or more of a merchant's stores.

getStoreList API does not require any additional input parameters, as the API Key uniquely identifies a merchant or his specific store. Depending on the type of API Key used, the results vary as follows:

  • API Key associated with a merchant: list of stores belonging to the merchant with that specific merchantId and meeting the search parameters.
  • API Key associated with a store: list containing the data of the individual store

Get a store list

Authorizations:
API-Key-Digest
query Parameters
limit
integer [ 1 .. 25 ]
Default: 10
Example: limit=5

Maximum number of stores to be fetched

match
string
Example: match=Apple

it can be used to search by store name, postal code or city

starAfter
string
Example: starAfter=lastStoreId

ID of the last store fetched. It is used to move forward in the pagination of results

header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": [
    ]
}

Check In

Get Pending Payment Requests

Authorizations:
API-Key-Digest
query Parameters
storeId
string
Example: storeId=storeId

Search for pending transactions only of the shop identified by storeId

header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": [
    ]
}

Accept Payment request

Authorizations:
API-Key-Digest
header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Request Body schema: application/json
transactionId
required
string

ID of the payment request to be accepted

Responses

Request samples

Content type
application/json
{
  • "transactionId": "transactionId"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Refuse Payment request

Authorizations:
API-Key-Digest
header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Request Body schema: application/json
transactionId
required
string

ID of the transaction to be refused

Responses

Request samples

Content type
application/json
{
  • "transactionId": "transactionId"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": {
    }
}

Transactions

Get Transactions

This API returns an array of transactions based on input parameters:

  • transactionId: returns the transaction with the given id
  • storeId: used to filter by store in the previous query
  • startTime, startAfter, limit: see description below
  • no parameters: the merchant's last 10 transactions
Authorizations:
API-Key-Digest
query Parameters
transactionId
string
Example: transactionId=transactionId

Id of the transaction to be retrieved. The response still contains an array containing a single transaction

storeId
string
Example: storeId=storeId

filter transactions by storeId

startTime
integer
Example: startTime=1697100695075

Unix Timestamp in milliseconds. This parameter allows searching for transactions with an equal or more recent endTime. If no startTime is provided, then transactions are sorted by decreasing endTime towards the least recent

startAfter
integer
Example: startAfter=transactionId

ID of the transaction to be used for paging. The results depend on the use of startTime:

  • in combination with startTime: paging to the most recent transactions. The parameter of startTime can remain the same as in the original query, while startAfter is the transactionId of the last transaction obtained in the previous query.
  • without startTime: paging toward the least recent transactions. The startAfter is the transactionId of the last transaction obtained in the previous query.
limit
integer [ 1 .. 25 ]
Default: 10
Example: limit=5

Maximum number of transactions to be fetched

header Parameters
x-maypay-req-id
required
string

Unique id of the request

date
required
string

Date string based on rfc7231 date format, i.e. 'Sun, 06 Nov 1994 08:49:37 GMT'

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "error": null,
  • "data": [
    ]
}