NAV
javascript shell ruby python

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:

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

Cons

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

Cons

Setup

To get to the point where you can use the payment widget or the API, you need to carry out some basic steps.

  1. Get your merchant ID from the Merchant Profile page.
  2. 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.
  3. 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:

This table lists the API calls supported for each API key type.

API Call Widget API Key Transaction API Key Admin API Key
Get markupXX
Get coinsXX
Get quoteXX
Create transactionXX
Update transactionXX
Get transaction by IdXX
Get transactionsX
Get transactions by IdsX

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 TypeAs explained above, the key type can be: Widget, Transaction or Admin.
Key NameIf you have more than 1 site, use the Key Name to identify which site a transaction is from.
Payment Markup PercentAllows 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 PercentAllows 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 WindowFrom 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.

  1. View the total price
  2. Select a coin to pay with / get the coin price converted from the currency total
  3. Deposit crypto into the address provided
  4. 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.

View total 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.

Select a coin / view payment amount

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.

Crypto payment - with QR code

The buyer also has the option of connecting a web3 compatible wallet such as Metamask or TrustWallet to make the payment.

Crypto payment - with wallet

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.

Crypto payment - you've paid

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.

Crypto payment - return to merchant

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
apiKeyMandatory: string, valid / enabled API keyThis needs to be an enabled widget API key, which can be created in the Integration / Api page.
merchantIdMandatory: stringThis 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
selectorMandatory: stringThe ID of the div element that the button is attached to.
buttonSizeMandatory: small | medium | largeControls the size of the Remuno payment button
variantMandatory: popup | inline | dialogControls 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.
popupPlacementtop | bottom (default) | left | rightControls where the payment widget popup form is displayed in relation to the button.
themelight (default) | darkLight theme or dark theme
showCoinProtocolBannertrue (default) | falseWhether 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: Coin banner example
quoteExpireAnimationMandatory: skew | throb | shakeWhen 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.
confirmCoinSelectiontrue | 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.
callbacksKey / Value objectIn 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.
selectedCoinsOptional: string arrayUsed 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.
notificationUrlOptional: valid URLURL to receive http POST notifications on the progress of the transaction. See the notification
marketRatetrue | 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.
summaryjavascript object:
summary: {
  template: "",
  variables: {}
}
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.
completeOnFullPaymentDetectedtrue | 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
amountMandatory: numeric - up to 2 decimal placesThe fiat value of the transaction.
fromFiatMandatory: USD | EUR | GBPThe currency to convert from.
orderIdMandatory: stringAn 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.
orderDescriptionOptional: stringOptional order description which will also displayed for each transaction in the dashboard.
customDetailsOptional: javascript objectOptional 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
templateMandatory: 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
variablesOptional: 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: {
  decimalAmount: (quote.quote.merchantQuote / quote.quote.marketExchangeRate * 10).toFixed(0),
  imageUrl: 'https://myimagesite.com/my.jpg'
}

The example from the code opposite will be shown in the widget as follows:

Market rate high price

Or, if the total price is reduced to $1 and has a minimum spend enforced for the selected coin:

Market rate low price

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
txnStatuspending |
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 yet
confirming - 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 completed
expired - the transaction payment window has expired. This may be with no payment or partial payment - check the paymentStatus field for the detail
paymentStatusno_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 yet
underpaid - 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 paid
overpaid - the transaction has been overpaid
failure - a failure occurred determining payment status
settlementStatusnot_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 yet
initiated - settlement has begun
confirming - the settlement transaction is confirming on the blockchain
transferred - the settlement has completed successfully
transfer_failure - a failure occurred during settlement
expired - the settlement expired after taking too long
transfer_failure_final - the settlement failed after many retries
insufficient_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 createdpendingno_paymentnot_settled
Payment detected on blockchainconfirmingno_paymentnot_settled
Blockchain payment completedreceivedpaidnot_settled
Settlement requiredreceivedpaidinitiated
Settlement confirmingreceivedpaidconfirming
Settlement completereceivedpaidtransferred

Successful Double Payment

Event txnStatus paymentStatus settlementStatus
Transaction createdpendingno_paymentnot_settled
Payment detected on blockchainconfirmingno_paymentnot_settled
Blockchain payment completed (buyer underpaid)receivedunderpaidnot_settled
Payment detected on blockchainconfirmingunderpaidnot_settled
Blockchain payment completed (buyer paid remainder)receivedpaidnot_settled
Settlement requiredreceivedpaidinitiated
Settlement confirmingreceivedpaidconfirming
Settlement completereceivedpaidtransferred

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 createdpendingno_paymentnot_settled
Payment detected on blockchainconfirmingno_paymentnot_settled
Blockchain payment completed (buyer overpaid)receivedoverpaidnot_settled
Settlement requiredreceivedoverpaidinitiated
Settlement confirmingreceivedoverpaidconfirming
Settlement completereceivedoverpaidtransferred

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 createdpendingno_paymentnot_settled
Payment detected on blockchainconfirmingno_paymentnot_settled
Blockchain payment completed (buyer underpaid)receivedunderpaidnot_settled
Settlement requiredreceivedunderpaidinitiated
Settlement confirmingreceivedunderpaidconfirming
Settlement completereceivedunderpaidtransferred

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
idMandatory: stringUnique Remuno identifier for the transaction.
txnStatuspending | confirming | received | expiredGives the overall status of payment blockchain transactions from the buyer.
orderIdstringThe orderId that was passed in the [Create Transaction](#create-transaction) call.
orderDescriptionstringThe order description that was passed in the [Create Transaction](#create-transaction) call.
walletAddressstringThe wallet address that funds should be sent to by the buyer.
fromFiatstringThe fiat currency specified in the quote supplied to the [Create Transaction](#create-transaction) call.
toCoinstringThe coin specified in the quote supplied to the [Create Transaction](#create-transaction) call.
toNetworkstringThe network that the coin specified in the quote supplied to the [Create Transaction](#create-transaction) call belongs to.
initialAmountstringThe amount specified in the quote supplied to the [Create Transaction](#create-transaction) call.
adjustedInitialAmountstringThe 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.
receivedAmountstringThe amount of coin so far received into the wallet address for payment so far.
merchantQuotestringThe amount of coin that the merchant will receive.
merchantReceivedAmountstringThe amount of coin that the merchant has actually received so far.
quotestringThe 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.
quoteExpiresAtstring: UTC ISO 8601 date / timeDate / time at which the quote given expires. If the quote expires, and the price has increased, the quote is automatically updated.
paymentExpiresAtstring: UTC ISO 8601 date / timeDate / 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.
paymentMarkupPercentdecimalThe payment markup percent assigned to the API key that was used to generate the quote.
minPaymentCompletePercentstringThe 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.
paymentExpiryPeriodSecondsnumericThe total number of seconds in the transaction payment window. After this period has elapsed either with underpayment or without payment, the transaction expires
merchantCustomDetailsJavascript objectOptional object containing merchant / transaction specific properties.
keyNamestringThe name of the API key that was used to create the transaction. This is assigned to each key in the merchant dashboard.
paymentStatusno_payment | underpaid | paid | overpaid | failureThe payment status of the transaction.
settlementStatusnot_settled | initiated | confirming | transferred | transfer_failure | expired | transfer_failure_finalThe settlement status of the transaction. This is the status of funds transfer back to the merchant address registered to the coin.
transactionTypedefault (Remuno rate transaction) | marketRate | unsolicitedType of transaction.
paymentNotificationUrlvalid URLThe optional notification URL that was passed to the Create Transaction call.
createdAtstring: UTC ISO 8601 date / timeThe date / time at which the transaction was created.
updatedAtstring: UTC ISO 8601 date / timeThe most recent date / time at which the transaction was updated.
sourceAddressesstring arrayArray of strings representing the source blockchain addresses which contributed to the Remuno transaction.
toFiatstringReserved for future use.
fromNetworkstringReserved for future use.
fromCoinstringReserved for future use.
nextPaymentStatusno_payment | underpaid | paid | overpaidWhen a transaction is clearing on the blockchain this indicates what the payment status will be when the transaction has been confirmed.
previousWalletTransactionIdstringOnly 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.

Dashboard notification test button

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.

Dashboard notification test button

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-keyExample API key: puiHsBoA9w57vLg3Vc1uLbWLnPg6ott5atAuthentication header
Content-Typeapplication/jsonFor 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
idMandatory: stringUnique Remuno identifier for the transaction.
txnStatuspending | confirming | received | expiredGives the overall status of payment blockchain transactions from the buyer.
orderIdstringThe orderId that was passed in the [Create Transaction](#create-transaction) call.
orderDescriptionstringThe order description that was passed in the [Create Transaction](#create-transaction) call.
walletAddressstringThe wallet address that funds should be sent to by the buyer.
fromFiatstringThe fiat currency specified in the quote supplied to the [Create Transaction](#create-transaction) call.
toCoinstringThe coin specified in the quote supplied to the [Create Transaction](#create-transaction) call.
toNetworkstringThe network that the coin specified in the quote supplied to the [Create Transaction](#create-transaction) call belongs to.
initialAmountstringThe amount specified in the quote supplied to the [Create Transaction](#create-transaction) call.
adjustedInitialAmountstringThe 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.
receivedAmountstringThe amount of coin so far received into the wallet address for payment so far.
merchantQuotestringThe amount of coin that the merchant will receive.
merchantReceivedAmountstringThe amount of coin that the merchant has actually received so far.
quotestringThe 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.
quoteExpiresAtstring: UTC ISO 8601 date / timeDate / time at which the quote given expires. If the quote expires, and the price has increased, the quote is automatically updated.
paymentExpiresAtstring: UTC ISO 8601 date / timeDate / 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.
paymentMarkupPercentdecimalThe payment markup percent assigned to the API key that was used to generate the quote.
minPaymentCompletePercentstringThe 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.
paymentExpiryPeriodSecondsnumericThe total number of seconds in the transaction payment window. After this period has elapsed either with underpayment or without payment, the transaction expires
merchantCustomDetailsJavascript objectOptional object containing merchant / transaction specific properties.
keyNamestringThe name of the API key that was used to create the transaction. This is assigned to each key in the merchant dashboard.
paymentStatusno_payment | underpaid | paid | overpaid | failureThe payment status of the transaction.
settlementStatusnot_settled | initiated | confirming | transferred | transfer_failure | expired | transfer_failure_finalThe settlement status of the transaction. This is the status of funds transfer back to the merchant address registered to the coin.
transactionTypedefault (Remuno rate transaction) | marketRate | unsolicitedType of transaction.
paymentNotificationUrlvalid URLThe optional notification URL that was passed to the Create Transaction call.
createdAtstring: UTC ISO 8601 date / timeThe date / time at which the transaction was created.
updatedAtstring: UTC ISO 8601 date / timeThe most recent date / time at which the transaction was updated.
sourceAddressesstring arrayArray 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
toFiatstringReserved for future use.
fromNetworkstringReserved for future use.
fromCoinstringReserved for future use.
nextPaymentStatusno_payment | underpaid | paid | overpaidWhen one or more transactions are confirming on the blockchain this indicates what the payment status will be when those transactions have been fully confirmed.
nextReceivedAmountstringWhen 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.
previousWalletTransactionIdstringOnly 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.