Blog » Guides

Blog Guides

Mar 2, 2020

Guide: Accept Cryptocurrency Payments with COINQVEST Merchant APIs

This guide will walk you through accepting cryptocurrency payments programmatically with minimal overhead. Make sales in Bitcoin, Ethereum, or any asset on the Stellar Network and settle in your preferred fiat currency (e.g. USD, EUR, or NGN) with a few lines of code.

Get Started

Getting paid online has just become a whole lot easier. Today, all you need is your favorite IDE and an HTTP REST client for your favorite programming language. If you're a seasoned web developer, jump right over to the API docs. Otherwise, this guide is just what you need to get started.


Collect your API key and secret for your account. Use your favorite REST client or our official libraries for access to the COINQVEST API from your application:


$client = new CQMerchantClient(

Our libraries automatically take care of authentication. If your programming language is not supported by any of our SDKs yet, then the authentication section in our API documentation walks you through our Digest or Basic-Auth authentication mechanisms step-by-step.

Create a Checkout

COINQVEST uses a checkout object to represent your intent to collect payment from a customer and track payment state changes throughout the process.

A checkout includes information about your charge, which customer the payment should be associated with and which currency you would like to get credited in when the payment completes.

First create a customer:

# create a customer
$response = $client->post('/customer', array('customer' => array(
    'email' => '',
    'firstname' => 'John',
    'lastname' => 'Doe',
    // more fields optional
$customerId = json_decode($response, true)['customerId']; // use this in the checkout

Then use it in a checkout:

#create a checkout
$response = $client->post('/checkout/hosted', array(
    'charge' => array(
        'customerId' => $customerId,
        'currency' => 'USD', // specifies the billing currency
        'lineItems' => array( // a list of line items included in this charge
                'description' => 'T-Shirt',
                'netAmount' => 10, // denominated in the currency specified above
                'quantity' => 1
        'shippingCostItems' => array( // any shipping costs?
                'description' => 'Shipping and Handling',
                'netAmount' => '3.99',
                'taxable' => false // sometimes shipping costs are taxable
        'taxItems' => array( // any taxes?
                'name' => 'CA Sales Tax',
                'percent' => '0.0825' // 8.25% CA sales tax
        'discountItems' => array( // an optional list of discounts
                'description' => 'Loyalty Discount',
                'netAmount' => '0.5'
    'settlementCurrency' => 'EUR' // specifies in which currency you want to settle
    'webhook' => '', // listen for payment events     
    'links' => array( // link targets on the hosted checkout page
        'returnUrl' => '',
        'cancelUrl' => ''

$data = json_decode($response, true); 
$checkoutId = $data['checkoutId']; // store this persistently for later reference
$checkoutUrl = $data['checkoutUrl']; // display this to your customer

Above request creates a hosted checkout on COINQVEST and returns a URL, which is displayed back to your customer. Upon visiting the URL the customer is presented with everything he needs in order to complete the payment. The hosted checkout UI is responsive and will play well with large desktop monitors as well as tiny mobile phone screens.

Hosted Checkout

COINQVEST automatically calculates the payment prices in supported cryptocurrencies, generates deposit addresses and monitors blockchains for inbound payments.

If you're not into hosted checkouts and prefer to implement a payment process entirely branded by you and fully hosted within your own web application, we got you covered. Have a look at our white-label checkout documentation.

Handle Post-Payment Events

COINQVEST sends a WEBHOOK payment event to your server when the payment completes. Use the webhook, your dashboard, or a third party solution, to receive this event and trigger actions like sending an order confirmation email to your customer, generating an invoice, logging the sale in your database, or starting a shipping workflow.

Example webhook payload:

  "id": "cb69affabf53",
  "customerId": "1acf0d0b10bd",
  "checkoutId": "87508a7a78c3",
  "type": "PAYMENT",
  "timestamp": "2020-03-02T16:04:50+02:00",
  "creditAssetCode": "USD",
  "creditAmount": "0.0100000",
  "sourceAssetCode": "XLM",
  "sourceAssetIssuer": "XLM:NATIVE",
  "sourceAmount": "0.1728238",
  "sourceBlockchain": "XLM",
  "sourceTxId": "0235acde7bb5c14536d534f816a69ccb66d4d4d95e8bbd5ca7b9c81c85790f7a"

Rather than waiting on the customer to be redirected back from the hosted checkout page, use the webhook for notification. The customer could close the browser window or quit the app before the callback executes. We also notify you via email about completed payments.

Alternatively, you can also choose to poll the GET /checkout endpoint to query payment state updates. However, using this method is probably more complex than simply waiting for WEBHOOK payment events server side.

$response = $client->get('/checkout', array('id' => $checkoutId));

if ($response->httpStatusCode == 200) {   
    $state = json_decode($response->responseBody, true)['checkout']['state'];
    if (in_array($state, array('COMPLETED', 'DELAYED_COMPLETED', 'RESOLVED'))) {
        // you can now ship the goods...
        echo "The payment has completed and your account was credited."
    } else {
        // try again in 30 seconds or so...

Query your Wallets

Completed payments are credited to your crypto- or fiat currency wallets on COINQVEST. You decide which currency you'd like to receive by setting the settlementCurrency attribute in the checkout request. It can be any crypto- or fiat currency supported by our platform. If you don't specify your settlement currency you are credited in the asset your customer paid with.

You can query all your wallets using GET /wallets or a specific currency like this:

$response = $client->get('/wallet', array('assetCode' => 'USD'));

Withdraw Funds

Once a payment has completed, it is instantly available in your wallet and the funds can be withdrawn to your bank account or any supported blockchain. For example, you can settle in Bitcoin but withdraw to your NGN bank account or to the Stellar Network instead. Use the POST /withdrawal endpoint to initiate a payout.

Withdraw USD to your NGN Bank Account:

$response = $client->post('/withdrawal', array(
    // withdraw from your USD wallet
    'sourceAmount' => '100',
    'targetNetwork' => 'NGN', // send to a NGN bank account
    'targetAccount' => array(
        'nuban' => '3080494548',
        'bankName' => 'FirstBank'

Withdraw USD to your Bitcoin Account:

$response = $client->post('/withdrawal', array(
    // withdraw from your USD wallet
    'sourceAmount' => '100',
    'targetNetwork' => 'BTC', // send to a BTC address
    'targetAccount' => array(
        'address' => 'bc1qj633nx575jm28smgcp3mx6n3gh0zg6ndr0ew23'

Withdraw USD to your Stellar Account:

$response = $client->post('/withdrawal', array(
    // withdraw from your USD wallet
    'sourceAmount' => '100',
    'targetNetwork' => 'XLM', // send to a Stellar account
    'targetAccount' => array(
        'memo' => 'Exodus',
        'memoType' => 'text'

With above request you can withdraw funds to any arbitrary asset on the Stellar Network directly, as long as a market exists on the Stellar Decentralized Exchange and the target account has a trustline for the target asset you are trying to send. Otherwise the withdrawal gracefully fails and provides additional error information.


Update a customer (PUT /customer):

$response = $client->post('/customer', array('customer' => array(
    'id' => 'fd4f47a50c7f',
    'email' => ''

Delete a customer (DELETE /customer):

$response = $client->delete('/customer', array('customer' => array(
    'id' => 'fd4f47a50c7f'

List your 250 newest checkouts (GET /checkouts):

$response = $client->get('/checkouts', array('limit' => 250));

List your 250 newest customers (GET /customers):

$response = $client->get('/customers', array('limit' => 250));

List all available blockchains (GET /blockchains):

$response = $client->get('/blockchains');

List all available fiat currencies (GET /fiat-currencies):

$response = $client->get('/fiat-currencies');


Please let us know anytime if there are questions or if there is anything else that we can assist you with. We're available via email and you can chat with us directly in our public Keybase channel coinqvest.public.

guidemerchant api
Marcin Olszowy COINQVEST Co-Founder