Madora Payments API
1.0.0

The Madora Payments API provides an easy way to accept Nano as a payment on your website, in your online store, video game, or other environment.

This is the documentation for version 1.0.0 of the API. Last update on Jun 8, 2022.

Base URL
https://madora.io

Authentication

Basic auth (http)

Madora.io uses HTTP Basic Authentication to verify all requests (see: https://en.wikipedia.org/wiki/Basic_access_authentication). API Access Keys may be generated on your Madora account page, after completing client onboarding. To make a request using a given key, the key should be combined with the secret in the form: key:secret, and then Base64 encoded. The encoded value can then added to the "Authorization" header as follows: Authorization: Basic [encoded_value]

Ipn secret key (http_api_key)

Instant Payment Notifications use a different authentication method than the rest of the API. A payment account has an IPN secret key associated with it, which can be accessed on the account page. This secret key is used to create a signature from the request, which is passed with all IPNs to verify that the source is legitimate. The signature will be passed in the header as x-madora-sig, and is created using HMAC and SHA256.


Create a new payment.

POST /api/payments/create-payment

Given an amount (in USD or raw nano), returns a payment identifier (used to track the payment in the Madora system) and a nano address to serve as the destination for the payee. The response contains payment amounts, payment address, and a unique identifier created by Madora to refer to the payment later. Payments will fail if the user does not complete them within 15 minutes, and a new payment will need to be created. As part of Madora's AML policy, payments may not exceed $600. Additionally, payments are only available in supported regions.

Body

Responses

  • 200 object

    200 OK

    • Unique identifier for the created payment.

    • usdAmount number(double)

      Required payment amount in USD. Will also except a string field, so long as it can be parsed into a number.

    • Required payment amount in Nano (Raw).

    • Required payment amount in Nano in a user-friendly format.

    • Nano address to be displayed to the user, which is where the payment should be sent to.

  • 400 object

    400 Bad Request

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 401 object

    401 Unauthorized

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 500 object

    500 Internal Server Error

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
POST /api/payments/create-payment
curl \
 -X POST https://madora.io/api/payments/create-payment \
 --user "username:password" \
 -H "Content-Type: application/json" \
 -d '{"usdAmount":"2.05","nanoAmount":"1000000000000000000000000000000","orderId":"1","orderDescription":"test transaction","paymentCustomer":{"firstName":"John","lastName":"Doe","email":"support@madora.io","organizationName":"Madora","country":"US","administrativeArea":"MA","subAdministrativeArea":"string","locality":"Boston","dependentLocality":"string","postalCode":"02133","thoroughfare":"24 Beacon St","premise":"string","subPremise":"string","phoneNumber":"+16177222000"}}'
Request example
{
  "usdAmount": "2.05",
  "nanoAmount": "1000000000000000000000000000000",
  "orderId": "1",
  "orderDescription": "test transaction",
  "paymentCustomer": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "support@madora.io",
    "organizationName": "Madora",
    "country": "US",
    "administrativeArea": "MA",
    "subAdministrativeArea": "string",
    "locality": "Boston",
    "dependentLocality": "string",
    "postalCode": "02133",
    "thoroughfare": "24 Beacon St",
    "premise": "string",
    "subPremise": "string",
    "phoneNumber": "+16177222000"
  }
}
Response example (200)
{
  "paymentIdentifier": "f390682f-4ded-41d6-adfd-80c54e85d73f",
  "usdAmount": 2.05,
  "rawNanoAmount": "1000000000000000000000000000000",
  "friendlyNanoAmount": "1.000000",
  "paymentAddress": "nano_3g6ue89jij6bxaz3hodne1c7gzgw77xawpdz4p38siu145u3u17c46or4jeu"
}
Response example (400)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (401)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (500)
{
  "errorCode": "internal",
  "errorMessage": "string"
}

Cancel a payment.

POST /api/payments/cancel-payment

Cancel a pending payment of the provided payment identifier. Will fail if the payment has already been cancelled, errored, or completed. Payments will automatically cancel if they are not completed after 15 minutes, which will mark them as errored.

Body

Responses

  • 200 object

    200 OK

    • paymentIdentifier string Required

      Unique identifier for the created payment.

    • status string Required

      Unique identifier for the created payment. Successful transactions will be marked as completed. Transactions that have failed due to technical reasons will be marked Error, while transactions that were flagged and denied by our Anti-Money Laundering program will be marked as AMLError. Transactions that are flagged will always automatically return money to the user.

      Values are Waiting, Cancelled, Error, AMLError, or Completed.

    • isComplete boolean Required

      Simple boolean to determine if a payment has successfully completed.

    • createdDatetime string(date-time) Required

      Datetime of when the payment was first created, in the format: uuuu-MM-dd'T'HH:mm:ss

    • orderId string

      Optional identifier for the transaction for merchant use. Not used by Madora.

    • Optional description for the transaction for merchant use. Not used by Madora.

  • 400 object

    400 Bad Request

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 401 object

    401 Unauthorized

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 500 object

    500 Internal Server Error

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
POST /api/payments/cancel-payment
curl \
 -X POST https://madora.io/api/payments/cancel-payment \
 --user "username:password" \
 -H "Content-Type: application/json" \
 -d '{"paymentIdentifier":"f390682f-4ded-41d6-adfd-80c54e85d73f"}'
Request example
{
  "paymentIdentifier": "f390682f-4ded-41d6-adfd-80c54e85d73f"
}
Response example (200)
{
  "paymentIdentifier": "f390682f-4ded-41d6-adfd-80c54e85d73f",
  "status": "Waiting",
  "isComplete": true,
  "createdDatetime": "2022-05-04T09:42:00+00:00",
  "orderId": "1",
  "orderDescription": "test transaction"
}
Response example (400)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (401)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (500)
{
  "errorCode": "internal",
  "errorMessage": "string"
}

Get the current status of a payment.

POST /api/payments/payment-status

Returns the current status of a payment given a unique payment identifier. Even if using webhooks, we recommend using this endpoint to verify payment completion.

Body

Responses

  • 200 object

    200 OK

    • paymentIdentifier string Required

      Unique identifier for the created payment.

    • status string Required

      Unique identifier for the created payment. Successful transactions will be marked as completed. Transactions that have failed due to technical reasons will be marked Error, while transactions that were flagged and denied by our Anti-Money Laundering program will be marked as AMLError. Transactions that are flagged will always automatically return money to the user.

      Values are Waiting, Cancelled, Error, AMLError, or Completed.

    • isComplete boolean Required

      Simple boolean to determine if a payment has successfully completed.

    • createdDatetime string(date-time) Required

      Datetime of when the payment was first created, in the format: uuuu-MM-dd'T'HH:mm:ss

    • orderId string

      Optional identifier for the transaction for merchant use. Not used by Madora.

    • Optional description for the transaction for merchant use. Not used by Madora.

  • 400 object

    400 Bad Request

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 401 object

    401 Unauthorized

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 500 object

    500 Internal Server Error

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
POST /api/payments/payment-status
curl \
 -X POST https://madora.io/api/payments/payment-status \
 --user "username:password" \
 -H "Content-Type: application/json" \
 -d '{"paymentIdentifier":"f390682f-4ded-41d6-adfd-80c54e85d73f"}'
Request example
{
  "paymentIdentifier": "f390682f-4ded-41d6-adfd-80c54e85d73f"
}
Response example (200)
{
  "paymentIdentifier": "f390682f-4ded-41d6-adfd-80c54e85d73f",
  "status": "Waiting",
  "isComplete": true,
  "createdDatetime": "2022-05-04T09:42:00+00:00",
  "orderId": "1",
  "orderDescription": "test transaction"
}
Response example (400)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (401)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (500)
{
  "errorCode": "internal",
  "errorMessage": "string"
}

Body

Responses

  • 200 object

    200 OK

  • 400 object

    400 Bad Request

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 401 object

    401 Unauthorized

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 500 object

    500 Internal Server Error

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
POST /api/payments/nano-to-usd
curl \
 -X POST https://madora.io/api/payments/nano-to-usd \
 --user "username:password" \
 -H "Content-Type: application/json" \
 -d '{"nanoAmount":"1000000000000000000000000000000"}'
Request example
{
  "nanoAmount": "1000000000000000000000000000000"
}
Response example (200)
{
  "usdAmount": "2.05"
}
Response example (400)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (401)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (500)
{
  "errorCode": "internal",
  "errorMessage": "string"
}

Body

Responses

  • 200 object

    200 OK

  • 400 object

    400 Bad Request

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 401 object

    401 Unauthorized

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
  • 500 object

    500 Internal Server Error

    • errorCode string Required

      Values are internal, invalidAmount, badInput, transactionTooLarge, unsupportedLocation, notEnabled, paymetNotFound, wrongAccount, alreadyCancelled, authMissing, or authInvalid.

    • errorMessage string Required
POST /api/payments/usd-to-nano
curl \
 -X POST https://madora.io/api/payments/usd-to-nano \
 --user "username:password" \
 -H "Content-Type: application/json" \
 -d '{"usdAmount":"2.05"}'
Request example
{
  "usdAmount": "2.05"
}
Response example (200)
{
  "nanoAmount": "1000000000000000000000000000000"
}
Response example (400)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (401)
{
  "errorCode": "internal",
  "errorMessage": "string"
}
Response example (500)
{
  "errorCode": "internal",
  "errorMessage": "string"
}

Returns supported countries and states.

GET /api/payments/supported

This endpoint returns all jurisdictions that Madora is able to operate in. This endpoint is the recommended option for providing client-side logic about whether to display Madora as a payment option. As Madora expands our compliance to new states, this endpoint will provide the most up-to-date list of allowed states.

Responses

GET /api/payments/supported
curl \
 -X GET https://madora.io/api/payments/supported \
 --user "username:password" \
 -H "apiKey: $API_KEY"
Response example (200)
{
  "supportedCountries": [
    "US"
  ],
  "supportedAdministrativeAreas": [
    "CA",
    "MA"
  ]
}

Emits when a payment has been completed.

POST /paymentConfirmation

Instant Payment Notifications (IPNs, also known as a webhook or callback) are used to quickly notify when a payment has been completed. When a payment is completed, the webhook will send a post request to the destination url configured on the Madora Payment Account. Responses to this webhook are ignored.

Body

  • paymentIdentifier string Required

    Unique identifier for the created payment.

  • status string Required

    Unique identifier for the created payment. Successful transactions will be marked as completed. Transactions that have failed due to technical reasons will be marked Error, while transactions that were flagged and denied by our Anti-Money Laundering program will be marked as AMLError. Transactions that are flagged will always automatically return money to the user.

    Values are Waiting, Cancelled, Error, AMLError, or Completed.

  • isComplete boolean Required

    Simple boolean to determine if a payment has successfully completed.

  • createdDatetime string(date-time) Required

    Datetime of when the payment was first created, in the format: uuuu-MM-dd'T'HH:mm:ss

  • orderId string

    Optional identifier for the transaction for merchant use. Not used by Madora.

  • Optional description for the transaction for merchant use. Not used by Madora.

POST paymentConfirmation
Request example
{
  "paymentIdentifier": "f390682f-4ded-41d6-adfd-80c54e85d73f",
  "status": "Waiting",
  "isComplete": true,
  "createdDatetime": "2022-05-04T09:42:00+00:00",
  "orderId": "1",
  "orderDescription": "test transaction"
}