Introduction
Welcome to the documentation for MoyaPay Payments API. Please note that we are currently in beta. If you run into any issues, or have questions / feedback on how we can improve, please let us know by sending a message to biz@moya.app.
API Reference
For the API reference, please visit MoyaPay Payments API Swagger
Authentication
To access the Messaging API, you will need an access token. In order to obtain one, please use the business portal to generate a merchant token.
The MoyaPay Payments API uses Bearer tokens for authentication (please see RFC-6750 standard for more information). You can pass the token as follows:
In the request headers (e.g. Authorization: Bearer YourSecretToken
)
Example
MoyaPay Merchant Python Example Integration
MoyaPay Merchant PHP Example Integration
Creating Payments
To initiate a payment that will open our Payment Gateway API, send a POST request to /payments/
as shown in our example.
HTTP Request
POST /payments/
Example Request
curl --location --request POST 'https://gateway.payments.moyapayd.app/payments/' \
--header 'Authorization: Bearer YourSecretToken' \
--header 'Content-Type: application/json' \
--data-raw '{
"amount": 50,
"redirectUrl": "https://moyapayd.app/buy-stuff/",
"webhookUrl": "https://moyapayd.app/buy-stuff/",
"username": "0710000000",
"reference": "Your Reference"
}'
Example Response:
{
"paymentID": "71dd2db9-e4f8-4345-ac2b-d17e15e7c184",
"redirectUrl": "https://ui.payments.moyapayd.app?paymentId=71dd2db9-e4f8-4345-ac2b-d17e15e7c184"
}
Example Error Response
{
"code": 400,
"status": "Bad Request",
"message": "Could not parse request body"
}
JSON Parameters
Name | Type | Required | Description |
---|---|---|---|
amount | int | Yes | This field is the amount of a payment in South African Rands in cents. E.g 50 = 0.5 ZAR, 500 = 5 ZAR. |
redirectUrl | String | Yes | Where the user will be redirected to once payment completed |
webhookUrl | String | Yes | The webhook endpoint that will be called when payment is completed. The JSON body included in our call to the endpoint will indicate the status of the payment. |
username | String | No | If user phone number is known, this can be passed to skip phone number enter screen on our Payment Gateway UI |
reference | String | No | A unique reference for your transaction. |
Result
The MoyaPay Payment Gateway API will signal success with an HTTP Status code 200 and a JSON object with a parameter paymentID
containing the id of the payment and a parameter redirectUrl
containing the URL for the Payment Gateway UI where the user should be redirected.
Error Result
An error will be signaled with HTTP Status codes 4xx and 5xx and a JSON payload with more details. The JSON payload is a complex object with the following parameters.
Name | Type | Required | Description |
---|---|---|---|
code | int | Yes | The returned error code |
error | String | Yes | The error that was returned for example: Unauthorized, Forbidden, Bad Request |
message | String | Yes | A detailed, human readable description of the error |
Querying Payments
To check the current state of a payment you can call our /payments/<paymentID>
endpoint.
HTTP Request
GET /payments/<paymentID>
Example Request
curl --location --request GET 'https://gateway.payments.moyapayd.app/payments/a8a7d09d-87bb-4eaa-8eb5-a6c4a5006a88' \
--header 'Authorization: Bearer YourSecretToken' \
--header 'Content-Type: application/json'
Example Response:
{
"paymentID": "a8a7d09d-87bb-4eaa-8eb5-a6c4a5006a88",
"state": "CREATED",
"merchantID": "datafree",
"merchantName": "MOYAPAYD (PTY) LTD",
"amount": 1,
"transactionID": null,
"userName": null,
"redirectUrl": "https://moyapayd.app/buy-stuff/",
"webhookUrl": "https://gateway.payments.moyapayd.app/payments/a8a7d09d-87bb-4eaa-8eb5-a6c4a5006a88/finalize",
"expiry": 1646048685
}
Result
The MoyaPay Payment Gateway API will signal success with an HTTP Status code 200 and a JSON object with the following parameters:
Name | Type | Required | Description |
---|---|---|---|
paymentID | String | Yes | The ID for the payment |
state | String | Yes | The current state of the payment, for example CREATED, ACCEPTED |
merchantID | String | Yes | Your merchant ID. This will be the same as your username on our Vendor Business Portal. |
merchantName | String | Yes | Your merchant name. This will be the same as your company name on our Vendor Business Portal. |
amount | String | Yes | The amount for the transaction in South African Rands in cents. E.g 50 = 0.5 ZAR, 500 = 5 ZAR. |
transactionID | String | Yes | The ID for this transaction. |
webhookUrl | String | Yes | The webhook endpoint that will be called when payment completed. |
expiry | int | Yes | When the payment will expire. |
Refund Payments
If you want to refund a payment that has been made you can call our /payments/<paymentID>/refund
endpoint. Refunds can only be made on payments that have been completed.
HTTP Request
POST /payments/<paymentID>/refund
Example Request
curl --location --request POST 'https://gateway.payments.moyapayd.app/payments/a8a7d09d-87bb-4eaa-8eb5-a6c4a5006a88/refund' \
--header 'Authorization: Bearer YourSecretToken' \
--header 'Content-Type: application/json' \
--data-raw '{"amount": 50}'
Result
The MoyaPay Payment Gateway API will signal success with an HTTP Status code 200.
Paying Customers
For paying into customers accounts you can call our /customers/pay
endpoint. This is called with an array of objects. Payments cannot be made to users that are not registered on MoyaPay.
HTTP Request
POST /customers/pay
Example Request
curl --location --request POST 'https://gateway.payments.moyapayd.app/customers/pay' \
--header 'Authorization: Bearer YourSecretToken' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"username": "27123456789",
"reference": "Price Money",
"amount": 50,
"beneficiaryName": "Example Name"
}
]'
Example Response:
[
{
"username": "0730000000",
"successful": true,
"message": "Successful",
}
]
Result
The MoyaPay Payment Gateway API will signal success with an HTTP Status code 200, and a list JSON objects with the following parameters:
Name | Type | Required | Description |
---|---|---|---|
username | String | Yes | The customers username |
successful | Boolean | Yes | Whether the payment was successful or unsuccessful |
message | String | Yes | A message about the payment, such as the reason it failed. |
Paying Customers Asynchronously
For paying into customers accounts asynchronously you can call our /customers/asyncpay
endpoint. This is called with an array of objects and a webhook url. The webhook url will be used to recieve results once the call is completed. Payments cannot be made to users that are not registered on MoyaPay.
HTTP Request
POST /customers/asyncpay
Example Request
curl --location --request POST 'https://gateway.payments.moyapayd.app/customers/asyncpay' \
--header 'Authorization: Bearer YourSecretToken' \
--header 'Content-Type: application/json' \
--data-raw '{
"payments": [
{
"username": "string",
"reference": "string",
"amount": 0,
"beneficiaryName": "string"
}
],
"webhookUrl": "string"
}'
Result
The MoyaPay Payment Gateway API will signal success with an HTTP Status code 202.
Checking Customers
If you want to check if a user has been registered on MoyaPay you can call our /customers/<customerID>/check
endpoint.
HTTP Request
GET /customers/<customerID>/check
Example Request
curl --location --request GET 'https://gateway.payments.moyapayd.app/customers/27123456789/check' \
--header 'Authorization: Bearer YourSecretToken' \
--header 'Content-Type: application/json'
Example Response:
### A fully registered customer
{
"success": true,
"resultCode": 2,
"resultMessage": "registered and verified"
}
#### An unregistered customer
{
"success": true,
"resultCode": 0,
"resultMessage": "not registered"
}
It will return a JSON Object with the customer's information. The result code can have 3 values as follows:
Result
Code | Message |
---|---|
0 | not registered (cannot make payments yet) |
1 | registered but not verified (cannot make payments yet) |
2 | registered and verified (can make payments) |
Frequently Asked Questions (FAQ)
Where to find the developer key/token?
For a developer key you will have to log into the business portal and navigate to the For Developers tab. There you should see the option to generate a new secret token. Once you click the Get New Token button you will be able to copy your private developer key. On this page you will also find a list of all your current active tokens and any revoked tokens you have.
How long do developer key/tokens last?
Developer keys are permanent but can be revoked.
What cell phone number format should be used?
The API expects the username (phone number) in international format (e.g. 27791112222).
It is also possible to use the username (phone number) in local format (e.g. 0791112222).
What content type can be used for the API calls?
Our API only accepts application/json
. Otherwise it will respond with 415 Unsupported Media Type
What payload formats can be used in API calls?
Only valid json structures can be sent in payload bodies. If the api responds with “400 Could not parse request body” please validate the body using a tool such as https://jsonlint.com/
Where do I find my username?
This will be the same as your username for the Merchant Portal