Home Development resources Point-of-Sale integration

Point-of-Sale integration

Last updated on Mar 25, 2025

Integrating Mion into a Point-of-Sale system is straightforward to do using our API. The process consists of three steps.

Make sure you have created an API key with the correct permissions. You can find the guide to creating and using API keys here. Remember to give the API key the Payments Read & Write permission.

1. Create a new payment session

Create a payment session by sending a POST request to the new payment session endpoint. This is where you specify the amount, currency, expiration, and internal reference. This endpoint requires authentication through an API key and should not be called in the frontend for security reasons.

After getting a successful response from the API, get the paymentSessionId from the JSON object returned. You will need this in the following steps to request payment attempts and check the status of the payment.

It is important to store the paymentSessionId, reference or both into your database, so that you can identify the payment session at Mion. The payment session ID is most convenient as this is the ID used by all Mion endpoints.

Notes:

  • Unless otherwise approved, EUR (Euro) is the only accepted value provided to the currencyIso3 parameter.

  • amount must be given in cents. For example, for 12 € set the amount to 1200. This is done to prevent floating point errors.

  • Payments on the Bitcoin blockchain can take hours, which is why we recommend only allowing Bitcoin over Lightning for Point-of-Sale integration. If you want to enable regular bitcoin payments, we recommend that you set a sufficiently long expiry time.

2. New Payment Attempt

With the payment session created, you can request a payment attempt by providing the paymentSessionId obtained above. The payment attempt contains the Lightning invoice, bitcoin amount, expiry time, and so on.

{
  "amountMsat": 25000000,
  "blockedByCompliance": false,
  "expiry": "2019-08-24T14:15:22Z",
  "lnInvoice": "string",
  "missingComplianceCustomerFields": [],
  "onChainAddress": "string",
  "paymentMethod": "lightning",
  "paymentSessionId": "75099bcf-22d5-43f9-8976-b7c5692eaa85",
  "suggestedFeeRate": 0
}

From this response we want to get amountMsat , expiry and lnInvoice for lightning payments.

The amountMsat field contains the amount of bitcoin to request from the customer denominated in "milli-satoshi". To get the bitcoin amount divide by amountMsat by 100 billion (amountMsat/(10^11)).

In the response above we got 25000000 mSat, which is 0.00025 Bitcoin, or 25,000 sat.

You can then display the Lightning invoice found in lnInvoice using a QR code, and the customer scans it using his or her favorite Lightning-enabled bitcoin wallet.

Note:

  • What is a milli-satoshi? The bitcoin amount is provided as "milli-satoshi" or "mSat" for short. To explain this further, similar to how there are 100 cents in 1 Euro, there are 100 million sat in 1 bitcoin (BTC). For example, 0.1 bitcoin is 10 million sat. To further prevent possible problems of divisibility in micro transactions, we operate with "milli sat" where we further divide a Satoshi by 1000.

  • Some Bitcoin users prefer seeing the bitcoin value presented as Satoshi ("sat" for short) because €10 is ₿0,00019, which is harder to read than 19,000 SAT. To get sat from mSat, divide by 1000.

3. Check Payment status

After the payment session is created, we need to check that the payment is completed. To do this, you request the payment status from the Mion backend. You should do this in your backend, then your frontend/client checks in with your own backend. This way you are certain that the payment is registered in your own systems.

We suggest you check every second or half a second to see if the payment succeeded.

"expiresAt": "2019-08-24T14:15:22Z",
"feeStatus": "correct",
"fundingAmountAvailable": 0,
"fundingStatus": "well-funded",
"paidAt": "2019-08-24T14:15:22Z",
"paymentMethod": "lightning",
"paymentSessionId": "75099bcf-22d5-43f9-8976-b7c5692eaa85",
"status": "draft"
}

Look for the Status being funded and that the paidAt times is set.

Note:

  • We will soon release documentation for using WebSocket in addition to polling (Rest API used as fallback).

Done

At this point your integration should be done. Please reach out to us on support@mion.group or to your account manager if you need help or there are errors in this guide.