Introduction
Welcome to the Remuno integration documentation! These pages are dedicated to get you working with our Crypto payments system in the way that's right for you. So we'll outline the integration options and their pros and cons, as well as giving in depth coverage of each option.
Why not sign up and create your own API key at our site if you haven't already done so:
Integration Methods
Currently we offer 2 main integration methods:
- The payment widget
- Custom integration with the Remuno Payment API
Payment Widget - Overview
The payment widget is the easiest option for integration that we offer currently. It consists of a mini Javascript app which you add to the checkout stage of your website. There's some lines of Javascript to add to your page and you also need to dynamically inject various parameters such as the price, currency and order ID. Once this is done, you get a "Checkout in Crypto" button on your page and when your buyer clicks this, we can complete their checkout in crypto. When the buyer has paid in full and we receive the funds, our processes ensure that you receive your basket amount. See the Payment Widget section below for more detail and some screenshots of the buyer experience.
Pros
- Simplest option for integrating Remuno crypto payments
- All the 'hard' development work has been done for you
- Very basic HTML skills to integrate
- Guides the buyer through the crypto payment process
Cons
- No branding control
- Limited customisation
Custom API Integration - Overview
When you decide to integrate directly with our API you're opting for full control over the buyer experience. Amongst other things, the API calls allow you to retrieve the list of coins that you support as a merchant, get a price quotation, create a transaction and check the transaction status. Using these calls you can knit together a completely custom experience for your buyer's crypto-based purchase. You can also receive webhook notifications on the status of your transaction.
Pros
- Complete control over the buyer experience - branding, customisation etc
Cons
- Requires sophisticated development skills to integrate
- Takes longer to integrate
Setup
To get to the point where you can use the payment widget or the API, you need to carry out some basic steps.
- Get your merchant ID from the Merchant Profile page.
- Decide which crypto coins you want to accept in the Accepted Coins page. If in doubt, just select all of the coins in the 'popular' tab when you're adding coins. For coins to appear in the payment widget or the
Get coins
API call, you will also need to add a wallet address to each coin, where you will receive your funds. - Create a Widget API key (payment widget) or a Transaction API Key (custom API integration) at the Integration / Api page.
API Keys
Regardless of the integration option you choose, you'll need to create an API key (Widget or Transaction).
API Keys Overview
We actually have 3 types of API keys in our system:
- Widget API keys: Use these only with the payment widget, they will be visible in the HTML of your web page
- Transaction API keys: These are intended for server side use, where they won't be visible on the web. Do not disclose these on the web!
- Admin API keys: Use these for API calls which are not directly involved in buyer transactions, e.g. retrieving a historic list of transactions. Do not disclose these on the web! Over time we will be growing the surface area of our API and the admin key will offer access to many aspects of your data.
This table lists the API calls supported for each API key type.
API Call | Widget API Key | Transaction API Key | Admin API Key |
---|---|---|---|
Get markup | X | X | |
Get coins | X | X | |
Get quote | X | X | |
Create transaction | X | X | |
Update transaction | X | X | |
Get transaction by Id | X | X | |
Get transactions | X | ||
Get transactions by Ids | X |
https://api.remuno.com/v1/merchants/<MerchantId>/coins
, e.g:
https://api.remuno.com/v1/merchants/MI00001AX/coins
API Key Settings
Each API key supports a number of settings. These are detailed below.
Setting Name | Description |
---|---|
Key Type | As explained above, the key type can be: Widget, Transaction or Admin. |
Key Name | If you have more than 1 site, use the Key Name to identify which site a transaction is from. |
Payment Markup Percent | Allows you to put a percentage markup on the transaction / basket price. The default is 0% and Remuno will take a small margin from any markup you specify. |
Payment Complete Percent | Allows you to be more tolerant to underpayments. As a percentage, you can consider 90-100% of the transaction value as fully paid. Default is 100%. |
Payment Window | From 15 minutes to 24 hours. How long the buyer has to complete the transaction. Default is 30 minutes, and the window extends everytime we receive a payment. This means the buyer can comfortably deposit from multiple sources if necessary to make up the full amount. |
Payment Widget
When you've signed up with us, you'll get access to the Integration / Payment widget page. Here you can generate the HTML code which you'll need to put in your website to integrate the payment widget. This is the easiest place to get a feel for how to configure the payment widget. You also get a chance to see how it works thanks to the live preview feature. That said, we'll cover all of the aspects of the payment widget that you'll need to know about here.
User Experience
The payment widget takes the buyer through a simple process.
- View the total price
- Select a coin to pay with / get the coin price converted from the currency total
- Deposit crypto into the address provided
- Confirm payment
Step 1: View total price
In the first step, the buyer is shown the total price to pay. If the API key has been configured with a markup (as per the image below), the markup is added at this point. If there is no markup, the price to pay is just the basket price.
In the Accepted Coins page, coins will be placed in the first list above if 'Is Promoted' is enabled. The order of the coins within the list can also be adjusted by using the arrows in the 'Change Order' column. Coins with 'Is Promoted' disabled can be found within the 'Other' drop-down list.
Step 2: Select coin / view amount to pay
Next, the buyer selects the crypto coin to pay with and is quoted a converted payment price. As crypto prices can change frequently, the buyer has a short period of time to confirm the amount and continue with the payment process.
Step 3: Payment
In the final step the buyer will be given a deposit address to send crypto to. To complete payment, the buyer must send crypto from a wallet they own, to the provided address. The image below shows the QR code option for payment.
The buyer also has the option of connecting a web3 compatible wallet such as Metamask or TrustWallet to make the payment.
Step 4: Payment Completion
Once the widget has detected the receipt of funds in full to the transaction wallet address, the payment screen briefly confirms the payment.
This is quickly replaced by the payment completion page which waits for a fixed period of time before hiding itself and returning control to the merchant website.
Simple HTML Integration
Here is an example of the
<head>
element. This should be placed at the end of the<head>
element if possible.
<script defer src="https://pay.remuno.com/widget.min.js" type="text/javascript"></script>
In the Integration / Payment widget page you can generate the HTML required to integrate with your shopping cart or web page. There are two parts to this. The first is required in the <head>
element of the page and loads the payment widget script. The second is the <body>
element additions which are supported by the widget script. The code opposite shows you how this fits together, but see the Widget API section for a comprehensive explanation of the methods and callbacks that the widget supports.
Visit our open source demo repo for example projects which demonstrate Remuno payment widget integration.
And here's an example of the widget definition itself which should be added to the
<body>
element of the page.[MerchantApiKey]
and[MerchantId]
should be replaced with the correct values.
<div id="payment-widget"></div>
<script type="text/javascript">
var remunoConfig = {
"selector": "#payment-widget",
"apiKey":"[MerchantApiKey]"
"merchantId": "[MerchantId]",
"amount": 20.33,
"fromFiat": "USD",
"variant": "dialog",
"theme": "light",
"orderId": "Order1965",
"buttonSize": "small",
"quoteExpireAnimation": "skew",
"showCoinProtocolBanner": true,
"confirmCoinSelection": false,
"marketRate": false
}
if (window.Remuno && window.Remuno.Widget) {
window.Remuno.Widget.init(remunoConfig)
} else {
window.Remuno = {
Widget: {
onLoad: function () {
window.Remuno.Widget.init(remunoConfig)
}
}
}
}
</script>
Widget Parameters
There are a number of widget parameters you can tap into to customize its behaviour. These are outlined below. Two fundamental parameters are the apiKey
and merchantId
described below. Without correct values for these, the payment widget won't be able to communicate with the Remuno payment API.
Parameter Name | Values | Description |
---|---|---|
apiKey | Mandatory: string, valid / enabled API key | This needs to be an enabled widget API key, which can be created in the Integration / Api page. |
merchantId | Mandatory: string | This is your unique merchant ID available from the Merchant Profile page. |
Widget-specific 'static' parameters. These parameters can be coded into the HTML statically: they don't need to change unless you specifically want to vary the widget behaviour across multiple buttons.
Parameter Name | Values | Description |
---|---|---|
selector | Mandatory: string | The ID of the div element that the button is attached to. |
buttonSize | Mandatory: small | medium | large | Controls the size of the Remuno payment button |
variant | Mandatory: popup | inline | dialog | Controls how the payment widget displays in relation to the rest of the web page. Note that the following behaviour may be affected by the specific layout of your page. Generally: dialog will display the widget as a form over the page, with elements in the page disabled. popup displays the widget immediately below the payment button over the top of surrounding content. inline displays the widget immediately below the payment button, pushing surrounding content down. |
popupPlacement | top | bottom (default) | left | right | Controls where the payment widget popup form is displayed in relation to the button. |
theme | light (default) | dark | Light theme or dark theme |
showCoinProtocolBanner | true (default) | false | Whether or not to display token protocols as a badge on top of the coin icon. The default is true and we recommend you leave these on to help with coin identification. Here's an example for ETH: ![]() |
quoteExpireAnimation | Mandatory: skew | throb | shake | When the payment window period expires without receiving full payment, the Refresh Quote button is displayed. This parameter controls the type of animation that is applied to the button to attract the buyer's attention. |
confirmCoinSelection | true | false (default) | When the coin has been selected and the user continues payment, if this setting is true, the buyer will be prompted to confirm their coin selection. This is off by default, to speed up the checkout process, but could be useful if your user base is less familiar with crypto payments. |
callbacks | Key / Value object | In the callbacks parameter you can specify javascript function names which will enable you to receive notifications of the progress of the transaction. The callbacks are: onOpen , onQuoteUpdated , onTransactionFailed , onTransactionCreated , onTransactionCompleted , onTransactionExpired , onTransactionCancelled and onClose . These are covered in detail in the next section.
|
selectedCoins | Optional: string array | Used to narrow the list of available coins presented to the user. E.g. if you just want to accept BTC, then pass an array like this: ['BTC']. Ensure the Remuno coin codes are used - these can be retrieved from the Get Coins endpoint. |
notificationUrl | Optional: valid URL | URL to receive http POST notifications on the progress of the transaction. See the notification |
marketRate | true | false (default) | Controls the type of transaction. A Remuno rate transaction is the default (marketRate = false), and in this transaction type the buyer pays the transaction costs. For a market rate transaction (marketRate = true), the buyer is shown the true market rate and the merchant pays the transaction costs. There may be minimum charges in place for market rate transactions to cover transaction fees, but this will be communicated to buyers when they select a coin. |
summary | javascript object:summary: { | For market rate transactions, the amount the merchant receives is dependent on the coin the buyer selects. Some coins have higher minimum amounts than others. For simple use cases, the summary parameter allows developers to recalculate how many items the buyer will receive and have this shown in the widget. See the Market Rate Example for a detailed explanation of how this works. |
completeOnFullPaymentDetected | true | false (default) | Coins such as Bitcoin and Doge can take some time to confirm on the blockchain. Setting completeOnFullPaymentDetected to true will successfully complete the transaction immediately that full payment has been detected on the blockchain. This gives a quicker payment experience for customers, but your payment flow should deal with potential transaction failure, should the transaction ultimately not be confirmed on the blockchain. (Though the chances of this are quite small.) This setting is suitable for applications such as gambling, where you can credit the customer account digitally (when nextPaymentStatus is paid or overpaid), but you also can reset the digital balance if the transaction fails (when paymentStatus is failure). It is also suitable for the purchase of physical goods as long as fulfilment is delayed until successful transaction completion (paymentStatus is paid or overpaid). |
Widget-specific 'dynamic' parameters. These parameters need to be injected into the widget config by the web page as a result of the purchase process.
Parameter Name | Values | Description |
---|---|---|
amount | Mandatory: numeric - up to 2 decimal places | The fiat value of the transaction. |
fromFiat | Mandatory: USD | EUR | GBP | The currency to convert from. |
orderId | Mandatory: string | An order reference used to identify the transaction. These will be displayed in your merchant dashboard for each transaction. They do not have to be unique, but if you query the API to return transactions with your order ID, you may get multiple results if you reuse Order IDs. |
orderDescription | Optional: string | Optional order description which will also displayed for each transaction in the dashboard. |
customDetails | Optional: javascript object | Optional javascript object to store along with the transaction. Upto around 1K of data can be stored. |
Widget API
<head>
<script defer src="https://pay.remuno.com/widget.min.js" type="text/javascript"></script>
</head>
<body>
<div id="payment-widget"></div>
<script type="text/javascript">
var callbacks = {
onOpen: () => console.log('WIDGET OPENED'),
onQuoteUpdated: (quote) => console.log('QUOTE UPDATED', quote),
onTransactionCompleted: (txn) =>
console.log('TXN COMPLETED SUCCESS'),
onTransactionExpired: (txn) => console.log('TXN COMPLETED FAIL'),
onTransactionCreated: (txn) => console.log('TXN CREATED SUCCESS'),
onTransactionFailed: (error) => console.log('TXN CREATED FAIL'),
onTransactionCancelled: (txn) =>
console.log(
`STATUS: ${txn.status}\nTXN_ID: ${txn.transaction?.id}`,
),
onClose: () => console.log('WIDGET CLOSED')
};
var remunoConfig = {
selector: "#payment-widget",
apiKey:"[MerchantApiKey]",
merchantId: "[MerchantId]",
callbacks: callbacks,
amount: 20.33,
fromFiat: "USD",
variant: "dialog",
theme: "light",
orderId: "Order1965",
buttonSize: "small",
quoteExpireAnimation: "skew",
showCoinProtocolBanner: true,
confirmCoinSelection: false,
marketRate: false
}
if (window.Remuno && window.Remuno.Widget) {
window.Remuno.Widget.init(remunoConfig)
} else {
window.Remuno = {
Widget: {
onLoad: function () {
window.Remuno.Widget.init(remunoConfig)
}
}
}
}
</script>
</body>
Transaction object definition for those callbacks which accept it:
{
"id": "vh41kzsnczizRi4Ef-jzN",
"txnStatus": "pending",
"orderId": "MyTestOrder0001",
"orderDescription": "",
"walletAddress": "0x6b3618fF07f18E9c4c0508e9C17666c2Ff03f6D2",
"fromFiat": "USD",
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "1.5",
"adjustedInitialAmount": "1.5",
"receivedAmount": "0",
"quote": "0.0068853",
"quoteExpiresAt": "2022-12-24T15:04:39.310Z",
"paymentExpiresAt": "2022-12-24T15:19:39.310Z",
"paymentMarkupPercent": 0,
"maxPaymentCompletePercent": "101",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"keyName": "key-qeYZs",
"paymentStatus": "no_payment",
"settlementStatus": "not_settled",
"paymentNotificationUrl": "",
"createdAt": "2022-12-24T14:49:39.311Z",
"updatedAt": "2022-12-24T14:49:39.311Z"
}
Overview
The widget script https://pay.remuno.com/widget.min.js
must be requested in the <head>
element of the page as per the example opposite. In the body element you must provide a <div>
element which the widget will be attached to. Following this, you will need to provide a script that initialises the widget. In this script, if the widget script has already loaded, it will have added a Remuno.Widget
object to the window and the init()
method can simply be called with the configuration object. (Remember to pass the div selector id as the selector
parameter.) If the widget script hasn't completed loading, then you can add a Remuno.Widget
object to the window with an onLoad
function. When the script has loaded it will call the onLoad
function you provide. Your function can then call the init
method.
Methods
onLoad
This method is provided by the developer and is optional. In a typical configuration, it will be used to call the init()
method of the widget when the page has loaded.
Definition
function onLoad() {}
init
Initialises the widget with a configuration object. See the Widget Parameters section for a full list of the parameters that can be passed via the configuration object. This must be done before activating the widget, so that it is fully initialised.
Definition
function init(remunoConfig) {}
updateConfig
This method is useful to update the widget with the more dynamic settings such as amount
, fromFiat
, orderId
, orderDescription
and customDetails
. It will accept a partial configuration object, so you only need to pass the parameters that have changed.
Definition
function updateConfig(partialRemunoConfig) {}
destroy
Completely destroys the widget, unmounting all components from the DOM.
Definition
function destroy() {}
Callbacks
onOpen
Called just before the widget is opened. It usually follows a click on the widget button.
Definition
function onOpen() {}
onQuoteUpdated
Called directly after the buyer selects a coin and is given a quote. This is useful in market rate transactions (marketRate
parameter is true
), where the Remuno fees are deducted from the total price. In this case, you can recalculate the goods / services the buyer will be given and display an appropriate message via the summary
parameter.
Definition
function onQuoteUpdated(quoteObj) {}
See the Get Quote endpoint response for the quote object definition.
onTransactionCreated
When the buyer accepts a quote and continues the payment process, the payment widget makes a call to the Remuno payment API to create a transaction. If this is successful, this callback is activated and is passed the transaction object received from the API. The widget then waits for the buyer to pay. This is a good point to capture the transaction ID from the transaction object. It's worth noting that this callback may be activated a number of times if the buyer cancels and returns to the widget.
Definition
function onTransactionCreated(createTxnObj) {}
See the Create Transaction endpoint response for the create transaction object definition.
onTransactionFailed
If the Create Transaction API call fails after a number of retries, this callback is activated and passed the error message(s).
Definition
function onTransactionFailed(errorMessages) {}
onTransactionCompleted
A transaction is considered successful if it has been paid in full, or even overpaid. If this is the case, this callback is activated and the final version of the transaction object passed into it.
Definition
function onTransactionCompleted(txnObj) {}
See the Get Transaction by Id endpoint response for the transaction object definition.
onTransactionExpired
If the transaction payment window expires, this callback is activated and passed the latest version of the transaction object. In this case, the transaction field txnStatus
will be set to expired
. The buyer may have transferred funds, but underpaid in this case.
Definition
function onTransactionExpired(txnObj) {}
See the Get Transaction by Id endpoint response for the transaction object definition.
onTransactionCancelled
This callback is activated when the buyer cancels the transaction. If a transaction was created, the callback is passed the transaction object.
Definition
function onTransactionCancelled(txnObj) {}
See the Get Transaction by Id endpoint response for the transaction object definition.
onClose
This is called just before the widget is closed. It can be activated by the user cancelling the widget, transaction expiration or payment completion.
Definition
function onClose() {}
Market Rate Example
Market rate widget configuration:
<html>
<head>
<script type='module' defer src="https://pay.remuno.com/widget.min.js" type="text/javascript"></script>
</head>
<body>
<div id="payment-widget"></div>
<script type="text/javascript">
const dollarCostPerElasticBand = 0.5
var callbacks = {
onQuoteUpdated: (quote) => window.Remuno.Widget.updateConfig({
selector: "#payment-widget",
summary: {
template: 'You will get:\n{d:decimalAmount} elastic bands {i:imageUrl:20px#20px}',
variables: {
decimalAmount: (quote.quote.merchantQuote / quote.quote.marketExchangeRate * dollarCostPerElasticBand).toFixed(0),
imageUrl: 'https://officesupplies-stationery.co.uk/wp-content/uploads/2022/05/fus_438896.jpg'
}
}
})
};
var remunoConfig = {
selector: "#payment-widget",
apiKey:"[MerchantApiKey]",
merchantId: "[MerchantId]",
callbacks: callbacks,
amount: 100.00,
fromFiat: "USD",
variant: "dialog",
theme: "light",
orderId: "Order1965",
buttonSize: "small",
quoteExpireAnimation: "skew",
marketRate: true
}
if (window.Remuno && window.Remuno.Widget) {
window.Remuno.Widget.init(remunoConfig)
} else {
window.Remuno = {
Widget: {
onLoad: function () {
window.Remuno.Widget.init(remunoConfig)
}
}
}
}
</script>
</body>
</html>
As detailed previously, setting the marketRate
widget parameter to true
supports the creation of a market rate transaction where the buyer is shown the true market rate for the selected coin and our fees are paid by the merchant and deducted from the overall amount. For each coin, we maintain minimum payment amounts for market rate transactions based on market conditions, so there is no way of knowing in advance how much the merchant will get from the transaction until a quote has been generated. For scenarios where there is a direct link between currency spent and the amount of items purchased the payment widget offers a simple way to show the buyer a recalculated description of amount purchased.
The summary
parameter allows the developer to specify a template string with replaceable parameters. See the code opposite for an example. This table breaks down the structure of the summary
object.
Summary Field | Values | Description |
---|---|---|
template | Mandatory: string | The template for the string that will be displayed in the payment widget when the quotation for a coin is initially displayed or changes. Supported features: \n - adds CRLF to the string when displayed {d:decimalVariable} - placeholder for a decimal number formatted according to the locale of the browser {i:imageUrlVariable:XXpx#YYpx} - placeholder for an image displayed XX x YY pixels |
variables | Optional: object | A key / value for each placeholder in the template string. E.g. if the template is 'You will get:\n{d:decimalAmount} elastic bands {i:imageUrl:20px#20px}' , then the variables object must contain definitions for decimalAmount and imageUrl as follows:variables: {
|
The example from the code opposite will be shown in the widget as follows:
Or, if the total price is reduced to $1 and has a minimum spend enforced for the selected coin:
Transaction Life Cycle
A transaction is created when calling the Create Transaction endpoint. (Visit this link for a detailed definition of the transaction object.) The endpoint may be called using direct integration with our API or via the payment widget. In either case a transaction object is generated and returned.
Determining Transaction Status
Determining transaction status with the payment widget is straightforward. The transactionCompletedSuccess callback is activated on successful payment. With direct integration, there are actually 3 status fields which work together to determine the overall status of a transaction.
Status Field | Values | Description |
---|---|---|
txnStatus | pending |confirming |received |expired |
This status field tracks the status of the blockchain transaction(s) created by the buyer as payment for the items in the transaction.pending - no transaction payment has been made yetconfirming - the transaction is confirming on the blockchain. Not all coins support this status, so txnStatus could transition from pending directly to received received - the blockchain transaction has been fully completedexpired - the transaction payment window has expired. This may be with no payment or partial payment - check the paymentStatus field for the detail
|
paymentStatus | no_payment |underpaid |paid |overpaid | failure |
This status field tracks the overall payment status of a transaction. If paymentStatus is overpaid or paid , the payment has been successful and the items purchased can be released.no_payment - no payment has been made yetunderpaid - the transaction is underpaid at this point in time. This takes into account the Payment complete percent value belonging to the API key in use. If Payment complete percent is set to 90% and the buyer pays 90-99% of the transaction value, then the payment status will be paid , rather than underpaid .paid - the transaction has been fully paidoverpaid - the transaction has been overpaidfailure - a failure occurred determining payment status
|
settlementStatus | not_settled |initiated |confirming |transferred | transfer_failure |expired |transfer_failure_final |insufficient_balance |
This status field tracks the progress of settling the payment to the merchant.
not_settled - settlement has not started yetinitiated - settlement has begunconfirming - the settlement transaction is confirming on the blockchaintransferred - the settlement has completed successfullytransfer_failure - a failure occurred during settlementexpired - the settlement expired after taking too longtransfer_failure_final - the settlement failed after many retriesinsufficient_balance - the payment was insufficient to be able to transfer. This can happen if a very small transaction amount is received
|
Example Transaction Flows
Successful Single Payment
Event | txnStatus | paymentStatus | settlementStatus |
---|---|---|---|
Transaction created | pending | no_payment | not_settled |
Payment detected on blockchain | confirming | no_payment | not_settled |
Blockchain payment completed | received | paid | not_settled |
Settlement required | received | paid | initiated |
Settlement confirming | received | paid | confirming |
Settlement complete | received | paid | transferred |
Successful Double Payment
Event | txnStatus | paymentStatus | settlementStatus |
---|---|---|---|
Transaction created | pending | no_payment | not_settled |
Payment detected on blockchain | confirming | no_payment | not_settled |
Blockchain payment completed (buyer underpaid) | received | underpaid | not_settled |
Payment detected on blockchain | confirming | underpaid | not_settled |
Blockchain payment completed (buyer paid remainder) | received | paid | not_settled |
Settlement required | received | paid | initiated |
Settlement confirming | received | paid | confirming |
Settlement complete | received | paid | transferred |
Buyer Overpays
An overpayment is a successful payment and is treated in the same way as a normal transaction in that we settle the merchant's portion of the transaction and take commission from it. We do this because of costs in processing any blockchain transaction. As a merchant you are free to refund the buyer the overpaid portion, minus our processing costs.
Event | txnStatus | paymentStatus | settlementStatus |
---|---|---|---|
Transaction created | pending | no_payment | not_settled |
Payment detected on blockchain | confirming | no_payment | not_settled |
Blockchain payment completed (buyer overpaid) | received | overpaid | not_settled |
Settlement required | received | overpaid | initiated |
Settlement confirming | received | overpaid | confirming |
Settlement complete | received | overpaid | transferred |
Buyer Underpays
An underpayment is an unsuccessful payment from the perspective of being able to release the items which the buyer purchased as part of the transaction. We treat underpayment in the same way as a normal transaction (provided there is enough payment), in that we settle the merchant's portion of the transaction and take commission from it. We do this because of costs in processing any blockchain transaction. As a merchant you are free to refund the buyer, minus our processing costs.
Event | txnStatus | paymentStatus | settlementStatus |
---|---|---|---|
Transaction created | pending | no_payment | not_settled |
Payment detected on blockchain | confirming | no_payment | not_settled |
Blockchain payment completed (buyer underpaid) | received | underpaid | not_settled |
Settlement required | received | underpaid | initiated |
Settlement confirming | received | underpaid | confirming |
Settlement complete | received | underpaid | transferred |
System Robustness
Remuno crypto payment processing is designed to be highly resilient. Generally failures will be transient and tolerated by initiating automatic retries. Once we have received payment from the end buyer (paymentStatus
is paid
or overpaid
), your systems are free to release the items which formed part of the transaction.
Transaction Notifications
Notifications Introduction
The transaction notification system will notify your server when the status of a transaction changes. Notifications are useful to automate order completion, digital goods release or other order completion processes.
Configuring Notifications
The status of transactions may be tracked by providing a notificationUrl
to the Create Transaction endpoint. This field is optional, but if supplied must be a valid http(s) URL capable of accepting a POST request.
Receiving Notifications
The notification posts a JSON body structured like this:
{
"id": "V2yX123BMawib1J_L_2T1",
"txnStatus": "pending",
"orderId": "Order0506",
"orderDescription": "",
"walletAddress": "0xc2119b5230C1811111111111135AA110d31111",
"fromFiat": "USD",
"toFiat": null,
"fromNetwork": null,
"fromCoin": null,
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "100",
"adjustedInitialAmount": "104",
"receivedAmount": "0",
"nextReceivedAmount": "0",
"merchantQuote": "0.3181745",
"merchantReceivedAmount": "0",
"quote": "0.3330121",
"quoteExpiresAt": "2023-04-13T15:24:50.856Z",
"paymentExpiresAt": "2023-04-13T15:39:50.856Z",
"paymentMarkupPercent": "4",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"merchantCustomDetails": {
"productId": "A78786X"
},
"keyName": "testest1",
"paymentStatus": "no_payment",
"nextPaymentStatus": "no_payment",
"settlementStatus": "not_settled",
"transactionType": "default",
"paymentNotificationUrl": "",
"previousWalletTransactionId": null,
"createdAt": "2023-04-13T15:09:50.857Z",
"updatedAt": "2023-04-13T15:09:50.857Z",
"sourceAddresses": []
}
Your notification endpoint will be called with a standard HTTP(S) POST request and should return a standard 200 OK HTTP response. If any other code is returned, we will retry up to 2 times, for 3 attempts in total. The json body of the post represents a standard transaction object as returned by the Get Transaction by Id endpoint.
Notification Field | Values | Description |
---|---|---|
id | Mandatory: string | Unique Remuno identifier for the transaction. |
txnStatus | pending | confirming | received | expired | Gives the overall status of payment blockchain transactions from the buyer. |
orderId | string | The orderId that was passed in the [Create Transaction](#create-transaction) call. |
orderDescription | string | The order description that was passed in the [Create Transaction](#create-transaction) call. |
walletAddress | string | The wallet address that funds should be sent to by the buyer. |
fromFiat | string | The fiat currency specified in the quote supplied to the [Create Transaction](#create-transaction) call. |
toCoin | string | The coin specified in the quote supplied to the [Create Transaction](#create-transaction) call. |
toNetwork | string | The network that the coin specified in the quote supplied to the [Create Transaction](#create-transaction) call belongs to. |
initialAmount | string | The amount specified in the quote supplied to the [Create Transaction](#create-transaction) call. |
adjustedInitialAmount | string | The amount plus the merchant markup against the API key being used. Will be the same as initalAmount if no markup. This is the value that will be converted to the coin specified by toCoin . |
receivedAmount | string | The amount of coin so far received into the wallet address for payment so far. |
merchantQuote | string | The amount of coin that the merchant will receive. |
merchantReceivedAmount | string | The amount of coin that the merchant has actually received so far. |
quote | string | The amount of coin that the user needs to transfer to the wallet address to fully pay for the transaction. This includes Remuno fees and so will be more than merchantQuote for Remuno transactions. |
quoteExpiresAt | string: UTC ISO 8601 date / time | Date / time at which the quote given expires. If the quote expires, and the price has increased, the quote is automatically updated. |
paymentExpiresAt | string: UTC ISO 8601 date / time | Date / time at which the entire transaction expires. If the transaction expires, txnStatus becomes expired and the transaction is no longer considered active at this point. This date / time is reset each time payment is received, giving the buyer ample time to complete the transaction. |
paymentMarkupPercent | decimal | The payment markup percent assigned to the API key that was used to generate the quote. |
minPaymentCompletePercent | string | The minimum percentage of payment that must be received in the target coin for the payment to be deemed complete. Derived from the API key that was used to generate the quote. |
paymentExpiryPeriodSeconds | numeric | The total number of seconds in the transaction payment window. After this period has elapsed either with underpayment or without payment, the transaction expires |
merchantCustomDetails | Javascript object | Optional object containing merchant / transaction specific properties. |
keyName | string | The name of the API key that was used to create the transaction. This is assigned to each key in the merchant dashboard. |
paymentStatus | no_payment | underpaid | paid | overpaid | failure | The payment status of the transaction. |
settlementStatus | not_settled | initiated | confirming | transferred | transfer_failure | expired | transfer_failure_final | The settlement status of the transaction. This is the status of funds transfer back to the merchant address registered to the coin. |
transactionType | default (Remuno rate transaction) | marketRate | unsolicited | Type of transaction. |
paymentNotificationUrl | valid URL | The optional notification URL that was passed to the Create Transaction call. |
createdAt | string: UTC ISO 8601 date / time | The date / time at which the transaction was created. |
updatedAt | string: UTC ISO 8601 date / time | The most recent date / time at which the transaction was updated. |
sourceAddresses | string array | Array of strings representing the source blockchain addresses which contributed to the Remuno transaction. |
toFiat | string | Reserved for future use. |
fromNetwork | string | Reserved for future use. |
fromCoin | string | Reserved for future use. |
nextPaymentStatus | no_payment | underpaid | paid | overpaid | When a transaction is clearing on the blockchain this indicates what the payment status will be when the transaction has been confirmed. |
previousWalletTransactionId | string | Only provided for unsolicited transactions. Gives the ID of the previous transaction in the same wallet. |
Validating Notifications
Node JS snippet for notification validation.
var express = require('express')
var CryptoJS = require('crypto-js')
var app = express();
app.use(express.json())
function isValidSignature(body, notificationKey, signatureHash) {
return CryptoJS.HmacSHA512(JSON.stringify(body), notificationKey).toString(CryptoJS.enc.Hex) === signatureHash
}
app.post('/notification-test', (req, res) => {
const notificationKey = ''; // enter your notification key here
const signatureHash = req.headers['x-remuno-sig'];
const isValid = isValidSignature(req.body, notificationKey, signatureHash);
console.log('Signature is valid: ', isValid)
res.send({ isValid })
})
module.exports = app;
var express = require('express')
var CryptoJS = require('crypto-js')
var app = express();
app.use(express.json())
function isValidSignature(body, notificationKey, signatureHash) {
return CryptoJS.HmacSHA512(JSON.stringify(body), notificationKey).toString(CryptoJS.enc.Hex) === signatureHash
}
app.post('/notification-test', (req, res) => {
const notificationKey = ''; // enter your notification key here
const signatureHash = req.headers['x-remuno-sig'];
const isValid = isValidSignature(req.body, notificationKey, signatureHash);
console.log('Signature is valid: ', isValid)
res.send({ isValid })
})
module.exports = app;
var express = require('express')
var CryptoJS = require('crypto-js')
var app = express();
app.use(express.json())
function isValidSignature(body, notificationKey, signatureHash) {
return CryptoJS.HmacSHA512(JSON.stringify(body), notificationKey).toString(CryptoJS.enc.Hex) === signatureHash
}
app.post('/notification-test', (req, res) => {
const notificationKey = ''; // enter your notification key here
const signatureHash = req.headers['x-remuno-sig'];
const isValid = isValidSignature(req.body, notificationKey, signatureHash);
console.log('Signature is valid: ', isValid)
res.send({ isValid })
})
module.exports = app;
var express = require('express')
var CryptoJS = require('crypto-js')
var app = express();
app.use(express.json())
function isValidSignature(body, notificationKey, signatureHash) {
return CryptoJS.HmacSHA512(JSON.stringify(body), notificationKey).toString(CryptoJS.enc.Hex) === signatureHash
}
app.post('/notification-test', (req, res) => {
const notificationKey = ''; // enter your notification key here
const signatureHash = req.headers['x-remuno-sig'];
const isValid = isValidSignature(req.body, notificationKey, signatureHash);
console.log('Signature is valid: ', isValid)
res.send({ isValid })
})
module.exports = app;
Your endpoint will receive an http header: x-remuno-sig
, for example
"x-remuno-sig":"31da212f7af62361283aad43759fe4d94999354ad95983a6e798d9c877ea12eb328d77fbf414f9c708e53d55a2ff52dc050aa532093961819073fe700e2f7f16"
This header should be validated to prevent your endpoint from being spoofed by third parties. In the Integration / Api page, there is a Payment Notification Key which we use to calculate the x-remuno-sig
hash. You can always regenerate the key on the dashboard page if you need to change it. See the code snippet opposite for how to use the notification key and the post body to validate the x-remuno-sig
signature hash.
Visit our open source demo repo for a demonstration of the validation.
Testing Notifications
You can test transaction notifications by visiting the Integration / Payment widget page and using the Test
button next to the Notification URL
field.
Pressing the Test
button will show the notification test form. Here you can select an event, such as Pending
, and your endpoint will be called with a transaction object in the requested state. The outcome usually takes a few seconds to be displayed in the Test results
table.
Payment API
console.log('Just groovy, baby...');
echo 'Just groovy, baby...'
puts 'Just groovy, baby...'
print 'Just groovy, baby...'
For our API, we have language bindings in Shell, Ruby, Python, and JavaScript. You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
You can also find a full live Swagger definition here: Swagger docs
Authentication
To authenticate, use this code:
require 'net/http'
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/coins')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = '<ThisIsMyVeryLongRemunoApiKey>'
response = http.request(request)
import requests
headers = {
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
response = requests.get('https://api.remuno.com/v1/merchants/<MerchantId>/coins', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.remuno.com/v1/merchants/<MerchantId>/coins" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>"
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/coins',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
Make sure to replace
<ThisIsMyVeryLongRemunoApiKey>
with your API key and<MerchantId>
with your merchant ID.
As part of authentication, the URL paths that you use to make Remuno API calls must include your Merchant Id. This is available from the Merchant Profile page. This table lists the required HTTP headers.
Header Name | Header Value | Description |
---|---|---|
x-api-key | Example API key: puiHsBoA9w57vLg3Vc1uLbWLnPg6ott5at | Authentication header |
Content-Type | application/json | For http POSTs: declare content type of Json |
Get Markup
require 'net/http'
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/markup')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = '<ThisIsMyVeryLongRemunoApiKey>'
response = http.request(request)
import requests
headers = {
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
response = requests.get('https://api.remuno.com/v1/merchants/<MerchantId>/markup', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.remuno.com/v1/merchants/<MerchantId>/markup" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>"
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/markup',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
{
"hideMarkupNotificationIfZeroMarkup": false,
"merchantName": "Test Merchant",
"markupPercent": 0,
"markupPercentPrice": 0,
"totalPrice": 1.5
}
This endpoint retrieves details related to the markup that you have applied to the API key used for authentication.
HTTP Request
GET https://api.remuno.com/v1/merchants/<MerchantId>/markup?price=1.5
URL Parameters
Parameter | Description |
---|---|
price | The decimal price of the transaction, i.e. the fiat equivalent that the buyer must pay. |
Permitted API Key Types
widget, payment
Response
Response Field | Description |
---|---|
hideMarkupNotificationIfZeroMarkup | Indicates whether the markup calculation section should be hidden on the payment widget if there is no markup. This is deprecated - the payment widget ignores this value and always hides the calculation if there is not merchant markup. |
merchantName | The name of your merchant as would be seen in the Merchant Profile page. |
markupPercent | The markup percentage applied to the API key you used in the API call. |
markupPercentPrice | The calculated value of the additional markup. |
totalPrice | This is price + markupPercentPrice: the total fiat equivalent that the buyer should pay. |
Get Coins
require 'net/http'
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/coins')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = '<ThisIsMyVeryLongRemunoApiKey>'
response = http.request(request)
import requests
headers = {
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
response = requests.get('https://api.remuno.com/v1/merchants/<MerchantId>/coins', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.remuno.com/v1/merchants/<MerchantId>/coins" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>"
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/coins',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
[{
"id": "CB6f1u3wprafLP6BdF9Wr",
"displayName": "Binance Coin (BSC)",
"displayCode": "BNB",
"code": "BNB_BSC",
"extraId": null,
"extraIdRegex": null,
"logoUrl": "/icons/bnb.png",
"network": "BNB_BSC",
"chainId": 56,
"tokenAddress": "",
"decimals": 18,
"protocol": "BEP-20",
"transferGasLimit": null,
"isPopular": true,
"isTrending": false,
"isStableCoin": false,
"isNativeCoin": true,
"isPromoted": true,
"order": 1
}, {
"id": "pYFvIIZNmsoXLA-niTpxw",
"displayName": "Bitcoin",
"displayCode": "BTC",
"code": "BTC",
"extraId": null,
"extraIdRegex": null,
"logoUrl": "/icons/bitcoin.png",
"network": "BTC",
"chainId": null,
"tokenAddress": "",
"decimals": 8,
"protocol": "",
"transferGasLimit": null,
"isPopular": true,
"isTrending": false,
"isStableCoin": false,
"isNativeCoin": true,
"isPromoted": true,
"order": 3
}
]
This endpoint retrieves the coins that your account accepts for payment. The Get Quote endpoint can be called with the code of a coin returned from this call.
HTTP Request
GET https://api.remuno.com/v1/merchants/<MerchantId>/coins
URL Parameters
None
Permitted API Key Types
widget, payment
Response
Response Field | Description |
---|---|
id | Remuno-specific unique coin identifier. |
displayName | Buyer-friendly coin description. |
displayCode | Buyer-friendly coin code. |
code | Remuno-specific coin code. This should be supplied to the Get Quote endpoint in the toCoin parameter. |
extraId | Buyer is required to enter this for some coin transfers, such as XRP. |
extraIdRegex | Regex to validate the extraId. |
logoUrl | Coin logo image URL, relative to remuno.com . |
network | The name of the network / blockchain the coin belongs to. |
chainId | The chain ID of the network (e.g. 1 for Ethereum) the coin belongs to. |
tokenAddress | If the coin is a token, this is the token contract address for the coin on the network. |
decimals | The maximum number of decimals supported after the decimal place (how divisible the coin is). |
protocol | The protocol for this coin on the network, e.g. ERC-20 for Ethereum. |
transferGasLimit | The gas limit to set for a simple transfer transaction for the coin, e.g. for wallet transfers. |
isPopular | Whether the coin is displayed on the 'Popular' tab when adding coins in the merchant dashboard. |
isTrending | Whether the coin is displayed on the 'Trending' tab when adding coins in the merchant dashboard. |
isStableCoin | Whether the coin is a stable coin - i.e. pegged to a fiat currency. USDT and BUSD are examples of stablecoins. |
isNativeCoin | Whether the coin is a native coin, e.g. BTC, ETH, DOGE, BNB BSC. |
isPromoted | Whether the coin should be shown in the first list of coins in the payment widget. |
order | If isPromoted is set true for a coin, determines the order of the coin within the first payment widget coin list. |
Get Quote
require 'net/http'
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/quote?toCoin=BNB_BSC&fromFiat=USD&amount=0.27')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = '<ThisIsMyVeryLongRemunoApiKey>'
response = http.request(request)
import requests
headers = {
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
response = requests.get('https://api.remuno.com/v1/merchants/<MerchantId>/quote?toCoin=BNB_BSC&fromFiat=USD&amount=0.27', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.remuno.com/v1/merchants/<MerchantId>/quote?toCoin=BNB_BSC&fromFiat=USD&amount=0.27" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>"
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/quote?toCoin=BNB_BSC&fromFiat=USD&amount=0.27',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
{
"quote": {
"fromFiat": "USD",
"toCoin": "BNB_BSC",
"marketRate": false,
"merchantQuote": "0.31927192857673727239",
"amount": "100",
"adjustedAmount": "104",
"quote": "0.334159",
"exchangeRate": "0.00320821",
"marketExchangeRate": "0.0031",
"networkFeesFiat": "0.16270376",
"networkFeesCoin": "0.000505",
"nonce": "a8996e6055ef0d0c7d0c797b1df855b4a91ebd47891ca6283ae426da8e011ef56ac5ea2a36d39f43ffd0bd3bc2501c63651968776c94f89164367052d6743a8cc388e1276a7bb0a9943f36bf719497dabe91dd86a9721b6e8d470cc472e722c462d80cafa77b59ab738076fa4c830b444f1235ca08955010eb5b2a3b182ec6c0044a53d9f729cb04b7d78d4344c5358ee5cec29e95d6e7abe0c7e666129a9b4c11d2704fb842bc5490024f595511586551da8589abcc835c30fb82398527adea91f80cc7345ba8baedce95a1e3a0a274845fd3d051650cb91dbcdba89d5c0e893bb48500ce61f66b4e0f4347075a23d812c26bc9d6af61d4b0223f11970bc6c8c778df67a2a8d82d2e9a",
"toNetwork": "BNB_BSC"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcm9tRmlhdCI6IlVTRCIsInRvQ29pbiI6IkJOQl9CU0MiLCJtYXJrZXRSYXRlIjpmYWxzZSwibWVyY2hhbnRRdW90ZSI6IjAuMzE5MjcxOTI4NTc2NzM3MjcyMzkiLCJhbW91bnQiOiIxMDAiLCJhZGp1c3RlZEFtb3VudCI6IjEwNCIsInF1b3RlIjoiMC4zMzQxNTkiLCJleGNoYW5nZVJhdGUiOiIwLjAwMzIwODIxIiwibWFya2V0RXhjaGFuZ2VSYXRlIjoiMC4wMDMxIiwibmV0d29ya0ZlZXNGaWF0IjoiMC4xNjI3MDM3NiIsIm5ldHdvcmtGZWVzQ29pbiI6IjAuMDAwNTA1Iiwibm9uY2UiOiJhODk5NmU2MDU1ZWYwZDBjN2QwYzc5N2IxZGY4NTViNGE5MWViZDQ3ODkxY2E2MjgzYWU0MjZkYThlMDExZWY1NmFjNWVhMmEzNmQzOWY0M2ZmZDBiZDNiYzI1MDFjNjM2NTE5Njg3NzZjOTRmODkxNjQzNjcwNTJkNjc0M2E4Y2MzODhlMTI3NmE3YmIwYTk5NDNmMzZiZjcxOTQ5N2RhYmU5MWRkODZhOTcyMWI2ZThkNDcwY2M0NzJlNzIyYzQ2MmQ4MGNhZmE3N2I1OWFiNzM4MDc2ZmE0YzgzMGI0NDRmMTIzNWNhMDg5NTUwMTBlYjViMmEzYjE4MmVjNmMwMDQ0YTUzZDlmNzI5Y2IwNGI3ZDc4ZDQzNDRjNTM1OGVlNWNlYzI5ZTk1ZDZlN2FiZTBjN2U2NjYxMjlhOWI0YzExZDI3MDRmYjg0MmJjNTQ5MDAyNGY1OTU1MTE1ODY1NTFkYTg1ODlhYmNjODM1YzMwZmI4MjM5ODUyN2FkZWE5MWY4MGNjNzM0NWJhOGJhZWRjZTk1YTFlM2EwYTI3NDg0NWZkM2QwNTE2NTBjYjkxZGJjZGJhODlkNWMwZTg5M2JiNDg1MDBjZTYxZjY2YjRlMGY0MzQ3MDc1YTIzZDgxMmMyNmJjOWQ2YWY2MWQ0YjAyMjNmMTE5NzBiYzZjOGM3NzhkZjY3YTJhOGQ4MmQyZTlhIiwidG9OZXR3b3JrIjoiQk5CX0JTQyIsImlhdCI6MTY4MTM5Njg5OSwiZXhwIjoxNjgxMzk3MDE5fQ.7US1EYSCfw-c39H9BnopKsBzKIasySodzb9jSmd1dj4"
}
This endpoint gets a price quotation from fiat to crypto.
HTTP Request
GET https://api.remuno.com/v1/merchants/<MerchantId>/quote
URL Parameters
Parameter | Description |
---|---|
fromFiat | Fiat from which to convert - USD, EUR or GBP. |
toCoin | Coin code returned from Get Coins endpoint. |
amount | Amount to convert. |
marketRate | Optional: true / false (default) - whether the transaction is a Remuno rate transaction (false) or a market rate transaction (true). A Remuno rate transaction is the default, and in this transaction type the buyer pays the transaction costs. For a market rate transaction , the buyer is shown the true market rate and the merchant pays the transaction costs. The quote may reflect a minimum charge for market rate transactions to cover transaction fees. |
Permitted API Key Types
widget, payment
Response
Response Field | Description |
---|---|
quote.fromFiat | Fiat specified by caller. |
quote.toCoin | Coin specified by caller. |
quote.marketRate | Whether the quote is a market rate based quote. |
quote.merchantQuote | How much the merchant will make from the quote. |
quote.toNetwork | Network / blockchain of target coin. |
quote.amount | Amount specified by caller. For market rate transactions this may be increased to reflect minimum transaction amounts. |
quote.adjustedAmount | Amount adjusted with merchant markup (if any) assigned to the active API key. For market rate transactions this may be increased to reflect minimum transaction amounts. |
quote.quote | Result of converting adjustedAmount in fiat to crypto coin specified. This is the crypto amount the buyer should actually pay. |
quote.exchangeRate | How much 1 unit of fiat currency is worth in the target coin. |
quote.networkFeesFiat | The cost of network fees in fiat. |
quote.networkFeesCoin | The cost of network fees in the target coin. |
quote.nonce | Prevents spoofing of quote. |
token | To be supplied to the Create Transaction endpoint to accept the quote and continue payment. |
Create Transaction
require 'net/http'
header = {'Content-Type': 'application/json', 'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'}
body = {
'orderDescription': 'My awesome items',
'orderId': 'Order4750',
'merchantCustomDetails': {
'productId': 'A78786X'
},
'quoteToken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcm9tRmlhdCI6IlVTRCIsInRvQ29pbiI6IkJOQl9CU0MiLCJhbW91bnQiOiIxIiwiYWRqdXN0ZWRBbW91bnQiOiIxIiwicXVvdGUiOiIwLjAwNDgwODciLCJleGNoYW5nZVJhdGUiOiIwLjAwNDIzMDgiLCJuZXR3b3JrRmVlc0ZpYXQiOiIwLjE0MTM4MTMiLCJuZXR3b3JrRmVlc0NvaW4iOiIwLjAwMDU3ODAiLCJub25jZSI6IjRlZWNiOGMwNGMwMThiMTYwZWQ3ZjlkOGU4YTFlYjczNzcxNjUxODkyYjAzZTMwNjA0NDZjMmQ4MTQzNTc2ODhmN2MzNzVmOWE1MWU1NmMxNTRkZmFmYjYzZThiNjU4NDdlZGY3ZDE3ZjE5YTBhZTdhYTgzM2FhOTU5OWU3MGE3OWZjZDkwYmJkM2UwZTQ0MGEyMWM5MTU2ZmE3ZjVmNDc1NGU3Mzg0ODNlYWY5NGRmMDZkYTRhZWM5ZTRlNjQ1NzJhZWVlOWQzYzJmZjdmYjI0ZDI0N2U5OGUwOGMwYWJiNjYxNDY1ZTgxMmFiZmRlOGEwNWQ3NTk1OTVhYjEzZmNhY2M1NTNkNjg4NTIzNjY0NTFkYWY2ZDBhODE3N2I0MThiM2UyNDllN2IwZjBiY2I0M2Q4ZTQ5NmM5ODFmZjUxODgyY2JmOWUzNTgyY2I1MGJjMDUxODNjY2JhNzM0MWE0ODNjNGY5MWEzNzZmMGM5MzlhMzRmZWMxYjAzNzAiLCJ0b05ldHdvcmsiOiJCTkJfQlNDIiwiaWF0IjoxNjcyMDA5MjYyLCJleHAiOjE2NzIwMTAxNjJ9.JR3HDvmtFA3smXvE-e39knhYOc11Qlk3KoNBC1LDfVQ'}
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/txns')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = body
response = http.request(request)
import requests
headers = {
"Content-Type": "application/json",
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
body = {
"orderDescription": "",
"orderId": "Order4750",
"merchantCustomDetails": {
"productId": "A78786X"
},
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcm9tRmlhdCI6IlVTRCIsInRvQ29pbiI6IkJOQl9CU0MiLCJhbW91bnQiOiIxIiwiYWRqdXN0ZWRBbW91bnQiOiIxIiwicXVvdGUiOiIwLjAwNDgwODciLCJleGNoYW5nZVJhdGUiOiIwLjAwNDIzMDgiLCJuZXR3b3JrRmVlc0ZpYXQiOiIwLjE0MTM4MTMiLCJuZXR3b3JrRmVlc0NvaW4iOiIwLjAwMDU3ODAiLCJub25jZSI6IjRlZWNiOGMwNGMwMThiMTYwZWQ3ZjlkOGU4YTFlYjczNzcxNjUxODkyYjAzZTMwNjA0NDZjMmQ4MTQzNTc2ODhmN2MzNzVmOWE1MWU1NmMxNTRkZmFmYjYzZThiNjU4NDdlZGY3ZDE3ZjE5YTBhZTdhYTgzM2FhOTU5OWU3MGE3OWZjZDkwYmJkM2UwZTQ0MGEyMWM5MTU2ZmE3ZjVmNDc1NGU3Mzg0ODNlYWY5NGRmMDZkYTRhZWM5ZTRlNjQ1NzJhZWVlOWQzYzJmZjdmYjI0ZDI0N2U5OGUwOGMwYWJiNjYxNDY1ZTgxMmFiZmRlOGEwNWQ3NTk1OTVhYjEzZmNhY2M1NTNkNjg4NTIzNjY0NTFkYWY2ZDBhODE3N2I0MThiM2UyNDllN2IwZjBiY2I0M2Q4ZTQ5NmM5ODFmZjUxODgyY2JmOWUzNTgyY2I1MGJjMDUxODNjY2JhNzM0MWE0ODNjNGY5MWEzNzZmMGM5MzlhMzRmZWMxYjAzNzAiLCJ0b05ldHdvcmsiOiJCTkJfQlNDIiwiaWF0IjoxNjcyMDA5MjYyLCJleHAiOjE2NzIwMTAxNjJ9.JR3HDvmtFA3smXvE-e39knhYOc11Qlk3KoNBC1LDfVQ"}
response = requests.post('https://api.remuno.com/v1/merchants/<MerchantId>/txns', headers=headers, json = body)
# With shell, you can just pass the correct header with each request
curl \
-H "Content-Type: application/json" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>" \
-X POST \
-d '{ "orderDescription": "", \
"orderId": "Order4750", \
"merchantCustomDetails": { \
"productId": "A78786X" \
}, \
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcm9tRmlhdCI6IlVTRCIsInRvQ29pbiI6IkJOQl9CU0MiLCJhbW91bnQiOiIxIiwiYWRqdXN0ZWRBbW91bnQiOiIxIiwicXVvdGUiOiIwLjAwNDgwODciLCJleGNoYW5nZVJhdGUiOiIwLjAwNDIzMDgiLCJuZXR3b3JrRmVlc0ZpYXQiOiIwLjE0MTM4MTMiLCJuZXR3b3JrRmVlc0NvaW4iOiIwLjAwMDU3ODAiLCJub25jZSI6IjRlZWNiOGMwNGMwMThiMTYwZWQ3ZjlkOGU4YTFlYjczNzcxNjUxODkyYjAzZTMwNjA0NDZjMmQ4MTQzNTc2ODhmN2MzNzVmOWE1MWU1NmMxNTRkZmFmYjYzZThiNjU4NDdlZGY3ZDE3ZjE5YTBhZTdhYTgzM2FhOTU5OWU3MGE3OWZjZDkwYmJkM2UwZTQ0MGEyMWM5MTU2ZmE3ZjVmNDc1NGU3Mzg0ODNlYWY5NGRmMDZkYTRhZWM5ZTRlNjQ1NzJhZWVlOWQzYzJmZjdmYjI0ZDI0N2U5OGUwOGMwYWJiNjYxNDY1ZTgxMmFiZmRlOGEwNWQ3NTk1OTVhYjEzZmNhY2M1NTNkNjg4NTIzNjY0NTFkYWY2ZDBhODE3N2I0MThiM2UyNDllN2IwZjBiY2I0M2Q4ZTQ5NmM5ODFmZjUxODgyY2JmOWUzNTgyY2I1MGJjMDUxODNjY2JhNzM0MWE0ODNjNGY5MWEzNzZmMGM5MzlhMzRmZWMxYjAzNzAiLCJ0b05ldHdvcmsiOiJCTkJfQlNDIiwiaWF0IjoxNjcyMDA5MjYyLCJleHAiOjE2NzIwMTAxNjJ9.JR3HDvmtFA3smXvE-e39knhYOc11Qlk3KoNBC1LDfVQ" }' \
"https://api.remuno.com/v1/merchants/<MerchantId>/txns"
var postData = JSON.stringify({
orderDescription: '',
orderId: 'Order4750',
merchantCustomDetails: {
productId: "A78786X"
},
quoteToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcm9tRmlhdCI6IlVTRCIsInRvQ29pbiI6IkJOQl9CU0MiLCJhbW91bnQiOiIxIiwiYWRqdXN0ZWRBbW91bnQiOiIxIiwicXVvdGUiOiIwLjAwNDgwODciLCJleGNoYW5nZVJhdGUiOiIwLjAwNDIzMDgiLCJuZXR3b3JrRmVlc0ZpYXQiOiIwLjE0MTM4MTMiLCJuZXR3b3JrRmVlc0NvaW4iOiIwLjAwMDU3ODAiLCJub25jZSI6IjRlZWNiOGMwNGMwMThiMTYwZWQ3ZjlkOGU4YTFlYjczNzcxNjUxODkyYjAzZTMwNjA0NDZjMmQ4MTQzNTc2ODhmN2MzNzVmOWE1MWU1NmMxNTRkZmFmYjYzZThiNjU4NDdlZGY3ZDE3ZjE5YTBhZTdhYTgzM2FhOTU5OWU3MGE3OWZjZDkwYmJkM2UwZTQ0MGEyMWM5MTU2ZmE3ZjVmNDc1NGU3Mzg0ODNlYWY5NGRmMDZkYTRhZWM5ZTRlNjQ1NzJhZWVlOWQzYzJmZjdmYjI0ZDI0N2U5OGUwOGMwYWJiNjYxNDY1ZTgxMmFiZmRlOGEwNWQ3NTk1OTVhYjEzZmNhY2M1NTNkNjg4NTIzNjY0NTFkYWY2ZDBhODE3N2I0MThiM2UyNDllN2IwZjBiY2I0M2Q4ZTQ5NmM5ODFmZjUxODgyY2JmOWUzNTgyY2I1MGJjMDUxODNjY2JhNzM0MWE0ODNjNGY5MWEzNzZmMGM5MzlhMzRmZWMxYjAzNzAiLCJ0b05ldHdvcmsiOiJCTkJfQlNDIiwiaWF0IjoxNjcyMDA5MjYyLCJleHAiOjE2NzIwMTAxNjJ9.JR3HDvmtFA3smXvE-e39knhYOc11Qlk3KoNBC1LDfVQ'
});
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/txns',
{
method: 'POST',
body: postData,
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
{
"id": "V2yXaZYBMawib1J_L_2T1",
"txnStatus": "pending",
"orderId": "Order0506",
"orderDescription": "",
"walletAddress": "0xc2119b5230C1811111111111135AA110d31111",
"fromFiat": "USD",
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "100",
"adjustedInitialAmount": "104",
"receivedAmount": "0",
"merchantQuote": "0.3181745",
"merchantReceivedAmount": "0",
"quote": "0.3330121",
"quoteExpiresAt": "2023-04-13T15:24:50.856Z",
"paymentExpiresAt": "2023-04-13T15:39:50.856Z",
"paymentMarkupPercent": "4",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"merchantCustomDetails": {
"productId": "A78786X"
},
"keyName": "testest1",
"paymentStatus": "no_payment",
"settlementStatus": "not_settled",
"transactionType": "default",
"paymentNotificationUrl": "",
"createdAt": "2023-04-13T15:09:50.857Z",
"updatedAt": "2023-04-13T15:09:50.857Z",
"sourceAddresses": []
}
This endpoint creates a transaction from a previously generate quote. The endpoint response provides the caller with a wallet address which the buyer must transfer funds into, to complete the transaction. The previous quote determines how much the buyer should pay.
HTTP Request
POST https://api.remuno.com/v1/merchants/<MerchantId>/txns
Post Parameters
Parameter | Description |
---|---|
orderId | An order reference which is not required to be unique. |
orderDescription | A description for the order. |
quoteToken | The token returned from a previous quote object. |
notificationUrl | A valid URL at which to receive notifications on the payment progress of the transaction. Multiple notifications will be received for a single transaction. |
merchantCustomDetails | An optional object containing any transaction specific properties you might want to store to help identify the transaction at a later date. E.g. { "productId": "A78786X" } |
Permitted API Key Types
widget, payment
Response
Response Field | Values | Description |
---|---|---|
id | Mandatory: string | Unique Remuno identifier for the transaction. |
txnStatus | pending | confirming | received | expired | Gives the overall status of payment blockchain transactions from the buyer. |
orderId | string | The orderId that was passed in the [Create Transaction](#create-transaction) call. |
orderDescription | string | The order description that was passed in the [Create Transaction](#create-transaction) call. |
walletAddress | string | The wallet address that funds should be sent to by the buyer. |
fromFiat | string | The fiat currency specified in the quote supplied to the [Create Transaction](#create-transaction) call. |
toCoin | string | The coin specified in the quote supplied to the [Create Transaction](#create-transaction) call. |
toNetwork | string | The network that the coin specified in the quote supplied to the [Create Transaction](#create-transaction) call belongs to. |
initialAmount | string | The amount specified in the quote supplied to the [Create Transaction](#create-transaction) call. |
adjustedInitialAmount | string | The amount plus the merchant markup against the API key being used. Will be the same as initalAmount if no markup. This is the value that will be converted to the coin specified by toCoin . |
receivedAmount | string | The amount of coin so far received into the wallet address for payment so far. |
merchantQuote | string | The amount of coin that the merchant will receive. |
merchantReceivedAmount | string | The amount of coin that the merchant has actually received so far. |
quote | string | The amount of coin that the user needs to transfer to the wallet address to fully pay for the transaction. This includes Remuno fees and so will be more than merchantQuote for Remuno transactions. |
quoteExpiresAt | string: UTC ISO 8601 date / time | Date / time at which the quote given expires. If the quote expires, and the price has increased, the quote is automatically updated. |
paymentExpiresAt | string: UTC ISO 8601 date / time | Date / time at which the entire transaction expires. If the transaction expires, txnStatus becomes expired and the transaction is no longer considered active at this point. This date / time is reset each time payment is received, giving the buyer ample time to complete the transaction. |
paymentMarkupPercent | decimal | The payment markup percent assigned to the API key that was used to generate the quote. |
minPaymentCompletePercent | string | The minimum percentage of payment that must be received in the target coin for the payment to be deemed complete. Derived from the API key that was used to generate the quote. |
paymentExpiryPeriodSeconds | numeric | The total number of seconds in the transaction payment window. After this period has elapsed either with underpayment or without payment, the transaction expires |
merchantCustomDetails | Javascript object | Optional object containing merchant / transaction specific properties. |
keyName | string | The name of the API key that was used to create the transaction. This is assigned to each key in the merchant dashboard. |
paymentStatus | no_payment | underpaid | paid | overpaid | failure | The payment status of the transaction. |
settlementStatus | not_settled | initiated | confirming | transferred | transfer_failure | expired | transfer_failure_final | The settlement status of the transaction. This is the status of funds transfer back to the merchant address registered to the coin. |
transactionType | default (Remuno rate transaction) | marketRate | unsolicited | Type of transaction. |
paymentNotificationUrl | valid URL | The optional notification URL that was passed to the Create Transaction call. |
createdAt | string: UTC ISO 8601 date / time | The date / time at which the transaction was created. |
updatedAt | string: UTC ISO 8601 date / time | The most recent date / time at which the transaction was updated. |
sourceAddresses | string array | Array of strings representing the source blockchain addresses which contributed to the Remuno transaction. |
Get Transaction by Id
require 'net/http'
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TransactionId>')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = '<ThisIsMyVeryLongRemunoApiKey>'
response = http.request(request)
import requests
headers = {
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
response = requests.get('https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TransactionId>', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TransactionId>" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>"
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TransactionId>',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
{
"id": "6q1234567vZGiP6-DU890",
"txnStatus": "pending",
"orderId": "3085110",
"orderDescription": "",
"walletAddress": "0xDE19bc12121212121212124302121212bA332",
"fromFiat": "USD",
"toFiat": null,
"fromNetwork": null,
"fromCoin": null,
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "0.27",
"adjustedInitialAmount": "0.28",
"receivedAmount": "0",
"nextReceivedAmount": "0",
"merchantQuote": "0.0008592",
"merchantReceivedAmount": "0",
"quote": "0.0014862",
"quoteExpiresAt": "2023-04-13T15:55:49.000Z",
"paymentExpiresAt": "2023-04-13T16:10:49.000Z",
"paymentMarkupPercent": "4",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"merchantCustomDetails": null,
"keyName": "testest1",
"paymentStatus": "no_payment",
"nextPaymentStatus": "no_payment",
"settlementStatus": "not_settled",
"transactionType": "default",
"paymentNotificationUrl": "",
"previousWalletTransactionId": null,
"createdAt": "2023-04-13T15:40:50.000Z",
"updatedAt": "2023-04-13T15:40:50.000Z",
"sourceAddresses": []
}
This endpoint fetches a single transaction by its ID.
HTTP Request
GET https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TransactionId>
URL Parameters
None
Permitted API Key Types
widget, payment
Response
It returns the same fields as documented in the Create Transaction endpoint with the following additions.
Response Field | Values | Description |
---|---|---|
toFiat | string | Reserved for future use. |
fromNetwork | string | Reserved for future use. |
fromCoin | string | Reserved for future use. |
nextPaymentStatus | no_payment | underpaid | paid | overpaid | When one or more transactions are confirming on the blockchain this indicates what the payment status will be when those transactions have been fully confirmed. |
nextReceivedAmount | string | When one or more transactions are confirming on the blockchain this indicates what the total received amount will be when those transactions have been fully confirmed. |
previousWalletTransactionId | string | Only provided for unsolicited transactions. Gives the ID of the previous transaction in the same wallet. |
Get Transactions
require 'net/http'
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/txns')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = '<ThisIsMyVeryLongRemunoApiKey>'
response = http.request(request)
import requests
headers = {
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
response = requests.get('https://api.remuno.com/v1/merchants/<MerchantId>/txns', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.remuno.com/v1/merchants/<MerchantId>/txns" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>"
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/txns',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
[
{
"id": "fGfxswLcGRQY3i0n3u2Vc",
"txnStatus": "pending",
"orderId": "9405391",
"orderDescription": "",
"walletAddress": "0xCD69ba2850D47a539888D9723d19a1f6F60C8Fe0",
"fromFiat": "USD",
"toFiat": null,
"fromNetwork": null,
"fromCoin": null,
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "1.08",
"adjustedInitialAmount": "1.08",
"receivedAmount": "0",
"nextReceivedAmount": "0",
"quote": "0.0044469",
"merchantReceivedAmount": "0",
"merchantQuote": "0.0038975467",
"quoteExpiresAt": "2023-01-19T15:04:24.000Z",
"paymentExpiresAt": "2023-01-19T15:19:24.000Z",
"paymentMarkupPercent": "0",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"userDetails": null,
"keyName": "key-qeYZs",
"paymentStatus": "no_payment",
"nextPaymentStatus": "no_payment",
"settlementStatus": "not_settled",
"paymentNotificationUrl": "",
"createdAt": "2023-01-19T14:49:24.000Z",
"updatedAt": "2023-01-19T14:49:51.000Z"
}
]
This endpoint returns a paginated array of transactions.
HTTP Request
GET https://api.remuno.com/v1/merchants/<MerchantId>/txns
URL Parameters
Parameter | Description |
---|---|
page | Numeric page indicator, defaults to 1 if not provided. |
pageSize | Numeric page size indicator, defaults to 10 if not provided. |
incompleteOnly | true or false (default) - returns transactions which have not completed yet. |
Permitted API Key Types
admin
Response
It returns an array of transactions. Each transaction contains the same fields as documented in the Get Transaction by Id endpoint.
Get Transactions by Ids
require 'net/http'
header = {'Content-Type': 'application/json', 'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'}
body = {
'ids': ['FN02hcd3Qmr9FjC-w3-Uf', 'tdBHpz-99SnkNLaGaNrE9']
}
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/txns/get-by-ids')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = body
response = http.request(request)
import requests
headers = {
"Content-Type": "application/json",
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
body = {
"ids": ["FN02hcd3Qmr9FjC-w3-Uf", "tdBHpz-99SnkNLaGaNrE9"]
}
response = requests.post('https://api.remuno.com/v1/merchants/<MerchantId>/txns/get-by-ids', headers=headers, json = body)
# With shell, you can just pass the correct header with each request
curl \
-H "Content-Type: application/json" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>" \
-X POST \
-d '{ "ids": ["FN02hcd3Qmr9FjC-w3-Uf", "tdBHpz-99SnkNLaGaNrE9"] }' \
"https://api.remuno.com/v1/merchants/<MerchantId>/txns/get-by-ids"
var postData = JSON.stringify({
ids: ['FN02hcd3Qmr9FjC-w3-Uf', 'tdBHpz-99SnkNLaGaNrE9']
});
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/txns/get-by-ids',
{
method: 'POST',
body: postData,
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
[
{
"id": "fGfxswLcGRQY3i0n3u2Vc",
"txnStatus": "pending",
"orderId": "9405391",
"orderDescription": "",
"walletAddress": "0xCD69ba2850D47a539888D9723d19a1f6F60C8Fe0",
"fromFiat": "USD",
"toFiat": null,
"fromNetwork": null,
"fromCoin": null,
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "1.08",
"adjustedInitialAmount": "1.08",
"receivedAmount": "0",
"nextReceivedAmount": "0",
"quote": "0.0044469",
"merchantReceivedAmount": "0",
"merchantQuote": "0.0038975467",
"quoteExpiresAt": "2023-01-19T15:04:24.000Z",
"paymentExpiresAt": "2023-01-19T15:19:24.000Z",
"paymentMarkupPercent": "0",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"userDetails": null,
"keyName": "key-qeYZs",
"paymentStatus": "no_payment",
"nextPaymentStatus": "no_payment",
"settlementStatus": "not_settled",
"paymentNotificationUrl": "",
"createdAt": "2023-01-19T14:49:24.000Z",
"updatedAt": "2023-01-19T14:49:51.000Z"
}
]
This endpoint returns a paginated array of transactions.
HTTP Request
POST https://api.remuno.com/v1/merchants/<MerchantId>/txns/get-by-ids
Post Parameters
Parameter | Description |
---|---|
ids | Array of strings containing 1 to 100 transaction Ids. |
Permitted API Key Types
admin
Response
It returns an array of transactions. Each transaction contains the same fields as documented in the Get Transaction by Id endpoint.
Update Transaction
require 'net/http'
header = {'Content-Type': 'application/json', 'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'}
body = {
'merchantCustomDetails': {
'productId': 'A78786X'
}
}
uri = URI.parse('https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TxnId>')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Patch.new(uri.request_uri, header)
request.body = body
response = http.request(request)
import requests
headers = {
"Content-Type": "application/json",
"x-api-key": "<ThisIsMyVeryLongRemunoApiKey>"
}
body = {
"merchantCustomDetails": {
"productId": "A78786X"
}
}
response = requests.post('https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TxnId>', headers=headers, json = body)
# With shell, you can just pass the correct header with each request
curl \
-H "Content-Type: application/json" \
-H "x-api-key: <ThisIsMyVeryLongRemunoApiKey>" \
-X PATCH \
-d '{ "merchantCustomDetails": { \
"productId": "A78786X" \
}' \
"https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TxnId>"
var patchData = JSON.stringify({
merchantCustomDetails: {
productId: "A78786X"
}
});
const response = await fetch('https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TransactionId>',
{
method: 'PATCH',
body: patchData,
headers: {
'Content-Type': 'application/json',
'x-api-key': '<ThisIsMyVeryLongRemunoApiKey>'
}
});
const data = await response.json();
console.log(data);
The above command returns JSON structured like this:
{
"id": "V2yX123BMawib1J_L_2T1",
"txnStatus": "pending",
"orderId": "Order0506",
"orderDescription": "",
"walletAddress": "0xc2119b5230C1811111111111135AA110d31111",
"fromFiat": "USD",
"toFiat": null,
"fromNetwork": null,
"fromCoin": null,
"toCoin": "BNB_BSC",
"toNetwork": "BNB_BSC",
"initialAmount": "100",
"adjustedInitialAmount": "104",
"receivedAmount": "0",
"nextReceivedAmount": "0",
"merchantQuote": "0.3181745",
"merchantReceivedAmount": "0",
"quote": "0.3330121",
"quoteExpiresAt": "2023-04-13T15:24:50.856Z",
"paymentExpiresAt": "2023-04-13T15:39:50.856Z",
"paymentMarkupPercent": "4",
"minPaymentCompletePercent": "100",
"paymentExpiryPeriodSeconds": 1800,
"merchantCustomDetails": {
"productId": "A78786X"
},
"keyName": "testest1",
"paymentStatus": "no_payment",
"nextPaymentStatus": "no_payment",
"settlementStatus": "not_settled",
"transactionType": "default",
"paymentNotificationUrl": "",
"previousWalletTransactionId": null,
"createdAt": "2023-04-13T15:09:50.857Z",
"updatedAt": "2023-04-13T15:09:50.857Z",
"sourceAddresses": []
}
This endpoint updates the merchantCustomDetails
field for a previous transaction.
HTTP Request
PATCH https://api.remuno.com/v1/merchants/<MerchantId>/txns/<TxnId>
Post Parameters
Parameter | Description |
---|---|
merchantCustomDetails | Javascript object containing merchant / transaction specific properties. |
Permitted API Key Types
widget, payment
Response
Full transaction object as per Get Transaction by Id.
Errors
The payment API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong or disabled, or your Merchant ID is wrong. |
405 | Method Not Allowed -- You tried to access an endpoint with an invalid method. |
406 | Not Acceptable -- You requested a format that isn't json. |
429 | Too Many Requests -- Rate limited for too many requests. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |