Token Slot

Bitcoin and Counterparty token redemption service.

Introduction

Token Slot is a cryptographic token redemption and payment processing service, currently with support for the Bitcoin (BTC) and Counterparty (XCP) protocols. This service can be used to allow for easy token redemption on any platform that connects to our API. All payments received by the system are forwarded to an address fully in your control on a daily basis, so there is minimal holding time for your funds.

The term "slot" is a reference to coin slots in vending machines, old arcade games, pay phones etc.. The basic idea is to insert X amount of tokens in to a machine/application in order to make it do something. This could be anything from a simple paywall or redemption for a physical product, to something more complex.

Used in combination with SwapBot and other Tokenly tools, a fully tokenized redeemable product ecosystem can emerge.


Basic Usage

For integration into your application, we recommend you use one of our libraries for connecting to the Token Slot API. Currently, we only have this library available in PHP (more languages coming soon). You can find the standalone PHP class on github. You can also find a version adapted for the Tokenly CMS here.

Getting Started

To get started, you will need to include the Client class in your project. You can use Composer, or just include the class file directly.

Via Composer, include the following in your composer.json file.

	"require": {
		"tokenly/tokenslot-client": "dev-master@dev"
	},

In your application, create a new instance of the TokenSlot-Client class.

	(if using composer package)
	$tokenslot = new \Tokenly\TokenSlotClient\Client(API_URL, API_KEY);
	
	(if using Tokenly CMS)
	$tokenslot  = new \API\TokenSlotClient(API_URL, API_KEY);

API_URL = https://slots.tokenly.com/api/v1
API_KEY = your client API key

Creating Payment Requests

The primary functionality of Token Slot is as a means of accepting tokens as payment for something, whether that be a physical product, a digital download, access to content or whatever else. When a new order or redemption is created in your application, Token Slot generates a fresh bitcoin address, unique to the customer. When the correct amount of tokens is received to the payment address, the payment request is marked as complete, and you may continue on to finalize the redemption (e.g, ship the product). All tokens received are regularly forwarded to an address of your choosing, twice a day. Payment requests automatically expire after 48 hours.

Step 1:

Before creating payment requests, you first need to create a "slot" for accepting a specific type of token. This tells the system where you want this type of token to go (if different than primary account forwarding address), how many confirmations required before payments are considered complete, among other options. See the API reference below for further details.

TokenSlot-Client provides a simple method for configuring a new slot before initializing new payments.

	$slot_alias = 'myslot_alias';
	$accepted_tokens = array('TOKENLY');
	$min_conf = 1;
	$slot = $tokenslot->getOrCreateSlot($slot_alias, $accepted_tokens, $min_conf)


Step 2:

Initialize a new payment request:

	//convert total to satoshi format by multiplying by 100,000,000
	$total = 1 * SATOSHI_MOD; 
	$payment_token = 'TOKENLY';
	$create_payment = $tokenslot->newPayment($slot['public_id'], $payment_token, $total);
	if($create_payment){
		$payment_id = $create_payment['payment_id'];
		$payment_address = $create_payment['address'];
		//save this information somewhere and display address to customer
	}
	else{
		//payment request failed
	}


Step 3:

After a payment request is created, there are two ways that you can check if the customer has completed their payment.

The first method is by simply querying the API.

	$check_complete = $tokenslot->checkPaymentComplete($payment_address);
	if($check_complete){
		//complete the order
	}
	else{
		//they have not paid the full amount yet
	}

The second method is by using webhooks. This requires the "webhook" field in your slot to be configured. Token Slot will post a notification (in JSON format) to your defined webhook whenever it sees a new incoming payment, or that payment has gained new network confirmations.

	$process_webhook = $tokenslot->receivePaymentsWebhook();
	if($process_webhook){
		//make sure data matches up to a pending redemption in your local database
		
		if($process_webhook['complete']){
			//complete order logic
		}
		else{
			//order not yet paid or not enough confirmations
		}
	}


Demos

Click here to view a basic front-end tech demo. (view source code)

Multiple token redemption w/ email notification (coming shortly)


API Reference

In order to access the API, you must first obtain an API key. Please contact us during this beta period if you would like to become an early use case.

All API methods accept requests and return responses in JSON format. If an error occurs, an appropriate HTTP status code is given (e.g 400, 403, 500), and an "error" field is included in the JSON response.

API endpoints look like this: https://slots.tokenly.com/api/v1/{endpoint/method}?key={my API key}

Quick links:

Methods

  • /api/v1/payments/request/{slot_id} [GET]

    Creates a new payment request and deposit address for the customer.

    Request method: GET
    Parameters:
    • token (string)
    • total (integer) - optional
    • reference (string) - optional
    • peg (string) - optional
    • peg_value (integer) - optional
    • forward_address (sting) - optional
    Returns:
    • Payment Request Object

    The token you wish to accept for this payment request must be in the list of accepted tokens for your slot.

    The total field should be the total amount of the order, in satoshis. If total is set to 0, it assumes a "pay what you want" type situation, and any valid transaction seen will cause the payment to be marked complete.

    The reference field can be used to store a custom identifier for the payment request, and should be unique per payment.

    You may use the peg and peg_total fields to create a payment request where the total value is pegged to the price of some other token or currency. For example, if you set token = LTBCOIN, peg = USD and peg_value = 1000, a total will be automatically generated for the equivilant of $10.00 worth of LTBCOIN. Cryptocurrency peg values should be measured in satoshis, and Fiat values in cents. The total does not need to be included when using pegged prices, since it is generated for you.

    A list of supported peggable tokens and currencies can be found here.

    The forward_address field allows you to set a custom routing address for funds from this specific payment to be forwarded to (defaults to address defined in slot or in account). Set this to an array in format {address: percentage, address2: percentage2} etc. to split payments between multiple addresses.

    The {slot_id} in the endpoint URL can be either the slot's unique ID or assigned "nickname", which can be used as an alias to the public ID.

  • /api/v1/payments/{payment_id} [GET]

    Gets the most up to date details on a specific existing payment request.

    Request method: GET
    Parameters: None
    Returns:
    • Payment Detail Object
  • /api/v1/payments/{payment_id}/cancel [POST]

    Cancels a payment request, which will stop Token Slot from monitoring new payments and mark it as "cancelled".

    Request method: POST
    Parameters: None
    Returns:
    • result (boolean)

    result field will be true if successful.

  • /api/v1/payments/all [GET]

    Retrieves a list of all payment requests associated with your client account / API key.

    Request method: GET
    Parameters:
    • incomplete (boolean) - optional
    • cancelled (boolean) - optional
    Returns:
    • Array of Payment Detail Objects

    If incomplete field is included and set to "true", then only payments which are not yet complete will be included. If set to "false", then it will return only completed payments. Exclude the incomplete field to get both.

    If cancelled is set to true, then closed/cancelled payment requests will be included in the response. This is false by default.

  • /api/v1/slots [GET]

    Retrieves a list of all "token slots" associated with your client account / API key.

    Request method: GET
    Parameters: None
    Returns:
    • Array of Slot Objects
  • /api/v1/slots [POST]

    Creates a new "token slot" attached to your account, for use with creating payment requests.

    Request method: POST
    Parameters:
    • tokens (array)
    • webhook (string) - optional
    • forward_address (string) - optional
    • min_conf (integer) - optional (defaults 0)
    • label (string) - optional
    • nickname (string) - optional
    Returns:
    • Slot Object

    The tokens field is an array of tokens which this slot will accept. They can be either BTC, or any token built on Counterparty, including XCP.

    webhook is the URL that you want the Token Slot service to send payment notifications to. Payment notifications are sent via a POST request using JSON formatting.

    forward_address is the Bitcoin address which you would like incoming tokens to be automatically forwarded to. Tokens received from payment requests are sent out twice a day, so we never hold your funds for long periods of time. If this field is left blank, your default forwarding address defined in your account will be used.
    Set this to an array in format {address: percentage, address2: percentage2} etc. to split payments between multiple addresses.

    min_conf is the minimum number of confirmations required before the system will mark a payment request as complete and stop sending notifications to your webhook. This number can be 0 or more... please use 0 confirmation transactions responsibly (do not accept 0-conf payments for a product or service which you cannot reverse in the event of an attempted double spend).

    The label field allows you to assign an internal reference label to the slot. This is for personal reference only.

    nickname allows you to set an alias for the slot, which can be used instead of the unique {public_id}. Example endpoint using a slot alias: /api/v1/payments/request/coffeepound_one

  • /api/v1/slots/{slot_id} [GET]

    Gets the basic details on a particular "slot"

    Request method: GET
    Parameters: None
    Returns:
    • Slot Object
  • /api/v1/slots/{slot_id} [PATCH]

    Updates slot details

    Request method: PATCH
    Parameters:
    • tokens (array) - optional
    • webhook (string) - optional
    • min_conf (integer) - optional
    • forward_address (string) - optional
    • label (string) - optional
    • nickname (string) - optional
    Returns:
    • Slot Object
  • /api/v1/slots/{slot_id} [DELETE]

    Deletes a "token slot" from the system.

    Request method: DELETE
    Parameters: None
    Returns:
    • result (boolean)

    Warning: this will also remove all associated payment requests.

  • /api/v1/slots/{slot_id}/payments [GET]

    Gets a list of all payment requests submitted for the specified slot.

    Request method: GET
    Parameters:
    • incomplete (boolean) - optional
    • cancelled (boolean) - optional
    Returns:
    • Array of Payment Detail Objects

    If incomplete field is included and set to "true", then only payments which are not yet complete will be included. If set to "false", then it will return only completed payments. Exclude the incomplete field to get both.

    If cancelled is set to true, then closed/cancelled payment requests will be included in the response. This is false by default.

Webhook Notifications

Token Slot automatically sends out notifications to your application each time it sees a transaction received for a payment request which you have made. The receiving notification end of your application is known as a "webhook".

When a payment request is initiated, Token Slot monitors (via XChain) the payment address for any newly received transactions. As soon as it is seen (even with 0 confirmations), a JSON formatted POST request is sent to the webhook defined in your "slot". An additional notification is sent each time something has changed with the payment (e.g additional confirmations have occurred). The webhook notifications stop being sent once the payment request has been completed or cancelled. If for some reason contacting the webhook fails (servers down?), it will retry a minute or so later, up to 30 times before giving up.

Payment Notification Fields:
  • id (integer)
  • time (timestamp)
  • attempt (integer)
  • payload (object)
    • payment_id (integer)
    • slot_id (string)
    • reference (string)
    • payment_address (string)
    • asset (string)
    • total (float)
    • total_satoshis (integer)
    • received (float)
    • received_satoshis (integer)
    • confirmations (integer)
    • init_date (timestamp)
    • complete (boolean)
    • complete_date (timestamp)
    • tx_info (array of Transaction Info Objects)
Sample JSON:
{  
   "id":329,
   "time":"2015-05-20T17:44:39+00:00",
   "attempt":1,
   "payload":"{\"payment_id\":\"36\",\"slot_id\":\"xiXyx5X2G3G3CIS1mg98\",\"reference\":\"0\",\"payment_address\":\"1Pck9kYC9fMjvahBhKrttiiWdjC2bxk1pT\",\"asset\":\"TOKENLY\",\"total\":1,\"total_satoshis\":\"100000000\",\"received\":1,\"received_satoshis\":100000000,\"confirmations\":0,\"init_date\":\"2015-05-20 17:44:28\",\"complete\":true,\"complete_date\":\"2015-05-20 17:44:39\",\"tx_info\":[{\"sources\":[\"1KthnhXAWmD6TuyjK3KbswVWvkuK3i2Keq\"],\"txid\":\"6755cc62874303303ae31a1303fd2b76c3db12dbb942abf053d334b1e051ac39\",\"amount\":100000000,\"confirmations\":0}]}"
}
			

Response Objects

Below you can find a list of the possible objects that may be returned by the RESTful API.

  • Payment Request
    Fields:
    • payment_id (integer)
    • address (string)
    • total (integer)*
    • peg (string)*
    • peg_value (integer)*
    • forward_address (string)
    Sample JSON:
    {
        "payment_id": 34,
        "address": "1CooQ7k4gApPeYsywTy5dpmBuB9Yqt9o3c",
        "total": 6366183636363,
        "peg": "USD",
        "peg_value": 1000,
        "forward_address": null    
    }
    						

    *note - total, peg and peg_value fields only available when using the price pegging feature

  • Payment Detail
    Fields:
    • id (integer)
    • address (string)
    • token (string)
    • total (integer)
    • received (integer)
    • peg (string)
    • peg_value (integer)
    • complete (boolean)
    • init_date (timestamp)
    • complete_date (timestamp)
    • reference (string)
    • tx_info (array of Transaction Info Objects)
    • slot_id (string)
    • cancelled (boolean)
    • cancel_time (timestamp)
    • forward_address (string)

    A payment request can receive multiple transactions, but all transactions must total up to the required amount and all have at least the min_conf amount of confirmations.

    The total and received fields are demoninated in satoshis.

    The peg is empty unless price pegging feature used. peg_value measured in satoshis or cents (depending on the peg)

    Sample JSON:
    {
        "id": 14,
        "address": "1NVvfJeysGF7ZwT75aNzuY7oyYwZDMQnXF",
        "token": "LTBCOIN",
        "total": 100000000,
        "peg": "",
        "peg_value": 0
        "received": 0,
        "complete": false,
        "init_date": "2015-05-14 14:32:04",
        "complete_date": null,
        "tx_info": null,
        "reference": "0",
        "slot_id": "xiXyx5X2G3G3CIS1mg98",
        "forward_address":
        {
            "15fx1Gqe4KodZvyzN6VUSkEmhCssrM1yD7": 50,
            "1Ao5a8QmNqMgjiE7xXcYkqjw9LjYy2YNzv": 50
        },    
    }
    						
  • Slot
    Fields:
    • public_id (string)
    • tokens (array)
    • webhook (string)
    • min_conf (integer)
    • forward_address (string)
    • label (string)
    • nickname (string)
    • created_at (timestamp)
    • updated_at (timestamp)

    A slot can be referenced be either its public_id or nickname field.

    Sample JSON:
    {
        "public_id": "znCFvFzeldWHF9BePxBv",
    	"tokens": [
    		"TOKENLY"
    	],
        "webhook": "https://example.org/tokenslot-hook",
        "min_conf": 1,
        "forward_address": "1KthnhXAWmD6TuyjK3KbswVWvkuK3i2Keq",
        "label": "demo_hook",
        "nickname": "demo",
        "created_at": "2015-05-14 01:04:28",
        "updated_at": "2015-05-14 01:04:28"
    }						
    						
  • Transaction Info
    Fields:
    • sources (array)
    • txid (string)
    • amount (integer)
    • confirmations (integer)

    sources is an array of bitcoin addresses involved in the transaction.

    confirmations are only tracked up to the min_conf field in the parent payment request's slot.

    Sample JSON:
    {
    	"sources": [
    		"1KthnhXAWmD6TuyjK3KbswVWvkuK3i2Keq"
    	],
    	"txid": "6755cc62874303303ae31a1303fd2b76c3db12dbb942abf053d334b1e051ac39",
    	"amount": 100000000,
    	"confirmations": 0
    }
    						

Contact Us

Token Slot is currently in a private beta, to get involved and become one of our early use cases, please contact team@tokenly.com.

For specific development inquiries, contact nick@tokenly.com.

© Tokenly 2018