NAV Navbar
Shell JavaScript
  • Introduction
  • Digital Goods API
  • HTML Tags
  • Retrieving Goods
  • Content Types
  • Introduction

    Welcome to the SatoshiPay API! You can use this API to make digital goods like articles, images, videos and downloadable files available for purchase using the SatoshiPay widget. This documentation covers:

    SatoshiPay and You

    To understand how SatoshiPay works you need to know the following:

    The following diagram illustrates how your website and SatoshiPay interact with each other:

    The SatoshiPay backend manages a registry of your digital goods. This registry contains pricing and some meta information, but not the content itself. You can register and manage these goods using the Digital Goods API.

    The goods can be embedded on your web page using HTML Tags with special data attributes. The location of the HTML tag determines the position of the digital good on the page, or if the good hasn't been paid yet, the position of its placeholder.

    The special HTML tags are recognised by the SatoshiPay widget, which needs to be included on every page that contains digital goods for sale. When a user buys a digital good, the widget handles the payment process by communicating to the SatoshiPay backend using a WebSocket connection. After successful payment the widget receives a payment receipt, which in turn is used to fetch the content of the good from a special HTTP Endpoint provided by you.

    Sun of Satoshi

    Include SatoshiPay Widget

    <script src="https://wallet.satoshipay.io/satoshipay.js"></script>
    

    We've nicknamed our website widget "Sun of Satoshi" to honour Bitcoin's anonymous creator Satoshi Nakamoto. It will float at the bottom right of the page and look like this:

    The widget displays a user's current balance in satoshis and, when clicked, a menu with items for top-up, settings and help. It can be included anywhere on any web page and will automatically transform SatoshiPay HTML Tags into digital goods. See it in action at the SatoshiPay website.

    The widget performs the following tasks:

    Digital Goods API

    Digital Goods API Endpoint

    https://api.satoshipay.io/v1/
    

    The Digital Goods API allows developers to interact with SatoshiPay using HTTP REST calls and JSON. Digital goods merchants communicate with the API in order to register individual goods for sale – either directly or through plugins and libraries provided by SatoshiPay or 3rd parties. The digital goods merchant hosts complementary HTTP Endpoints that deliver the goods to the user.

    General

    Authentication

    Basic Authentication

    curl https://api.satoshipay.io/v1/goods \
      -u <api-key>:<api-secret>
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods",
      auth: {
        user: "<api-key>",
        password: "<api-secret>"
      }
    }, callback);
    

    Every request to the API must be authenticated with your API credentials. These credentials can be obtained in the SatoshiPay Dashboard after creating an account. Before you can access your credentials, you need to set a Bitcoin address for payouts. Your API key and secret can then be found at Settings > API Access.

    The API uses Basic Authentication, where the user name is your API key, and the password is your API secret.

    The example uses Basic Authentication to receive the list of your goods. The result will be an empty array [] if you didn't add any goods yet.

    If authorization fails, a JSON object with an error message will be returned as a response (along with the HTTP status 401) .

    Content Types

    curl https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559 \
      -X PATCH \
      -u apikey:apisecret \
      -H 'Content-Type: application/json' \
      -d '{ "sharedSecret": "xyz" }'
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      method: "PATCH",
      json: {
        sharedSecret: "xyz"
      }
    }, callback);
    

    All endpoints respond with JSON objects.

    For POST, PUT or PATCH requests, the request body needs to be valid JSON. Also make sure to include a Content-Type: application/json header in your requests.

    Errors

    Example Error Object

    {
      "name": "unauthorized",
      "message": "Unauthorized Request",
      "statusCode": 401,
      "errorCode": 401
    }
    

    If an error occurs while handling the request, a JSON error object will be returned along with a corresponding HTTP status code. The object contains status and error codes, the name of the error, as well as the error message.

    Goods

    The API resource goods allows a merchant to manage their digital goods. A good in the API represents a merchant's digital good (e.g. news article, image, audio/video or file download) and holds all information needed for SatoshiPay to handle payments. This includes pricing information and other metadata, but not the content itself.

    List Goods

    Definition

    GET https://api.satoshipay.io/v1/goods
    

    Example Request

    curl https://api.satoshipay.io/v1/goods \
      -u apikey:apisecret
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      json: true
    }, callback);
    

    Example Response

    [
      {
        "id": "56c5a2a4f1cc5c0448c429f2",
        "price": 9106,
        "sharedSecret": "n1hLnMiJwAwB",
        "url": "https://example.info",
        "title": "Tempora accusamus maxime similique veritatis magni."
      },
      {
        "id": "56c5a2a52362b70448a589b4",
        "price": 1349,
        "sharedSecret": "m1btHMWJ6O6g",
        "url": "http://example.name",
        "title": "Saepe voluptatibus tempore pariatur atque quia corrupti nisi dolores."
      }
    ]
    

    GET goods

    Get a list of all goods a merchant has created.

    Response

    Returns an array of 'good' objects. Every object has the following properties:

    Property Type Description
    id string Unique identifier of the good.
    price integer Good's price in satoshis.
    sharedSecret string Shared secret information which will be used to sign the paymentReceipt used to authenticate user during digital goods retrieval.
    url string URL of the web page which contains the good. Used as a reference in the Dashboard.
    title string Title of the good for reference in the provider dashboard.

    Create a Good

    Definition

    POST https://api.satoshipay.io/v1/goods
    

    Example Request

    curl https://api.satoshipay.io/v1/goods \
      -u apikey:apisecret \
      -H 'Content-Type: application/json' \
      -X POST \
      -d '{
           "sharedSecret": "DLDwYsQGromi",
           "price": 6247,
           "title": "Nihil placeat sapiente ut eaque assumenda et reprehenderit quos ab.",
           "url": "http://example.org/post1"
          }'
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      method: "POST",
      json: {
        "sharedSecret": "DLDwYsQGromi",
        "price": 6247,
        "title": "Nihil placeat sapiente ut eaque assumenda et reprehenderit quos ab.",
        "url": "http://example.org/post1"
      }
    }, callback);
    

    Example Response

    {
      "id": "56c5a5a722252b484dc4839f",
      "sharedSecret": "DLDwYsQGromi",
      "price": 6247,
      "title": "Nihil placeat sapiente ut eaque assumenda et reprehenderit quos ab.",
      "url": "http://example.org/post1"
    }
    

    POST goods

    Create a new good.

    Request

    Provide a 'good' object with the following properties:

    Property Type Required Description
    price integer yes Good's price in satoshis.
    sharedSecret string yes Shared secret information which will be used to sign the paymentReceipt used to authenticate user during digital goods retrieval.
    url string yes URL of the web page which contains the good. Used as a reference in the Dashboard.
    title string yes Title of the good for reference in the provider dashboard.

    Response

    As a confirmation, the handler returns the an object representing the good from the request, augmented by an id property, which holds the ID that has been assigned to the good as a string.

    Retrieve a Good

    Definition

    GET https://api.satoshipay.io/v1/goods/<id>
    

    Example Request

    curl https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559 \
      -u apikey:apisecret
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      json: true
    }, callback);
    

    Example Response

    {
      "id": "558bcdbb1309c59725bdb559",
      "sharedSecret": "m1btHMWJ6O6g",
      "price": 1349,
      "title": "Saepe voluptatibus tempore pariatur atque quia corrupti nisi dolores.",
      "url": "http://example.name"
    }
    

    GET goods/<id>

    Retrieve a specific good identified by <id>. If no good with the given ID can be found, an error object with status code 404 is returned.

    Request

    Insert the ID of the good into the request URL.

    Response

    A 'good' object with the following properties:

    Property Type Description
    id string Unique identifier of the good.
    price integer Good's price in satoshis.
    sharedSecret string Shared secret information which will be used to sign the paymentReceipt used to authenticate user during digital goods retrieval.
    url string URL of the web page which contains the good. Used as a reference in the Dashboard.
    title string Title of the good for reference in the provider dashboard.

    Replace a Good

    Definition

    PUT https://api.satoshipay.io/v1/goods/<id>
    

    Example Request

    curl https://api.satoshipay.io/v1/goods/56c5a91265e80b7c51afad23 \
      -u apikey:apisecret \
      -H 'Content-Type: application/json' \
      -X PUT \
      -d '{
            "sharedSecret": "RLC43wvCcmcs",
            "price": 4806,
            "title": "Veritatis impedit mollitia nam ipsum laudantium quam quidem.",
            "url": "https://example.net"
          }'
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      method: "PUT",
      json: {
        "sharedSecret": "RLC43wvCcmcs",
        "price": 4806,
        "title": "Veritatis impedit mollitia nam ipsum laudantium quam quidem.",
        "url": "https://example.net"
      }
    }, callback);
    

    Example Response

    {
      "id": "56c5a91265e80b7c51afad23",
      "sharedSecret": "RLC43wvCcmcs",
      "price": 4806,
      "title": "Veritatis impedit mollitia nam ipsum laudantium quam quidem.",
      "url": "https://example.net"
    }
    

    PUT goods/<id>

    Replace the good given by <id>. If no good with the given ID exists, an error object with status code 404 will be returned.

    Request

    Insert the ID of the good that should be replaced into the request URL and provide a 'good' object that will replace the old good with the given id. The object has the following properties:

    Property Type Required Description
    price integer yes Good's price in satoshis.
    sharedSecret string yes Shared secret information which will be used to create paymentReceipt used to authenticate user during digital goods retrieval.
    url string yes URL of the web page which contains the good. Used as a reference in the Dashboard.
    title string yes Title of the good for reference in the provider dashboard.

    Response

    As a confirmation, the handler returns an object representing the good from the request, including the id property with type string.

    Update a Good

    Definition

    PATCH https://api.satoshipay.io/v1/goods/<id>
    

    Example Request

    curl https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559 \
      -u apikey:apisecret \
      -H 'Content-Type: application/json' \
      -X PATCH \
      -d '{
            "url": "http://example.com/changed"
          }'
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      method: "PATCH",
      json: {
        "url": "http://example.com/changed"
      }
    }, callback);
    

    Example Response

    {
      "id": "56c5a82328383fe54f841a60",
      "sharedSecret": "XyZtFohL7",
      "price": 1799,
      "title": "Beatae ab autem delectus dolorem est fugiat.",
      "url": "http://example.com/changed"
    }
    

    PATCH goods/<id>

    Partially update a good, i.e. send only those properties that are to be updated.

    Request

    Insert the ID of the good that should be updated into the request URL and provide an 'update' object that has any subset of the following properties. The specified properties will then overwrite the properties of the good with the given id in the request URL.

    Property Type Required Description
    price integer no Good's price in satoshis.
    sharedSecret string no Shared secret information which will be used to create paymentReceipt used to authenticate user during digital goods retrieval.
    url string no URL of the web page which contains the good. Used as a reference in the Dashboard.
    title string no Title of the good for reference in the provider dashboard.

    Response

    The updated 'good' object.

    Delete a Good

    Definition

    DELETE https://api.satoshipay.io/v1/goods/<id>
    

    Example Request

    curl https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559 \
      -u apikey:apisecret \
      -X DELETE
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/goods/558bcdbb1309c59725bdb559",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      method: "DELETE"
    }, callback);
    

    DELETE goods/<id>

    Delete a good.

    Request

    Insert the ID of the good to be deleted into the request URL.

    Batch Requests

    Definition

    POST https://api.satoshipay.io/v1/batch
    

    Example Request

    curl https://api.satoshipay.io/v1/batch \
      -u apikey:apisecret \
      -H 'Content-Type: application/json' \
      -X POST \
      -d '{
            "requests": [
              {
                "method": "POST",
                "path": "/goods",
                "body": {
                  "sharedSecret": "NSKLDspUuo_V",
                  "price": 1182,
                  "title": "Aliquam sit nisi quia ut rerum.",
                  "url": "https://example.com/post1"
                }
              },
              {
                "method": "POST",
                "path": "/goods",
                "body": {
                  "sharedSecret": "NSfg1elotk_R",
                  "price": 7343,
                  "title": "Vitae facere ea totam hic",
                  "url": "https://example.com/post2"
                }
              }
            ]
          }'
    
    var request = require("request");
    request({
      url: "https://api.satoshipay.io/v1/batch",
      auth: {
        user: "apikey",
        password: "apisecret"
      },
      method: "POST",
      json: {
        "requests": [
          {
            "method": "POST",
            "path": "/goods",
            "body": {
              "sharedSecret": "NSKLDspUuo_V",
              "price": 1182,
              "title": "Aliquam sit nisi quia ut rerum.",
              "url": "https://example.com/post1"
            }
          },
          {
            "method": "POST",
            "path": "/goods",
            "body": {
              "sharedSecret": "NSfg1elotk_R",
              "price": 7343,
              "title": "Vitae facere ea totam hic",
              "url": "https://example.com/post2"
            }
          }
        ]
      }
    }, callback);
    

    Example Response

    {
      "responses": [
        {
          "status": 200,
          "body": {
            "id": "56c59f4092d316b1419591eb",
            "sharedSecret": "NSKLDspUuo_V",
            "price": 1182,
            "title": "Aliquam sit nisi quia ut rerum.",
            "url": "https://example.com/post1"
          }
        },
        {
          "status": 200,
          "body": {
            "id": "56c59f4092d316b1419591ec",
            "sharedSecret": "NSfg1elotk_R",
            "price": 7343,
            "title": "Vitae facere ea totam hic.",
            "url": "https://example.com/post2"
          }
        }
      ]
    }
    

    POST batch

    Execute a batch of requests at once.

    Request

    Provide an array of 'request' objects in the body. Each request object has the following properties:

    Property Type Required Description
    method string yes The method of the query. Has to be one of POST, PUT, PATCH or DELETE.
    path string yes The path of the resource. For example: /goods/<id>
    body json value depending on method JSON value that represents the body of the request.

    Response

    Returns an array of 'response' objects that each correspond to the respective request from the request array. Each response object has the following properties:

    Property Type Description
    status integer HTTP status code of the respective request.
    body json value JSON value that represents the response body from the respective request.

    HTML Tags

    Digital goods can be included on a web page by defining special HTML tags, which will then be controlled by the SatoshiPay widget. Content types for text, images, audio files, videos and downloads are supported. Find a complete list of supported types in the reference section.

    Before purchase, a digital good is represented on the merchant's website by a placeholder. These placeholders are injected by the SatoshiPay widget, which scans the current page for placeholder tags on initialization. The placeholder tags are identified by a CSS class name starting with satoshipay-placeholder and contain details about the good they replace in their data attributes (see the text tag example).

    Goods placeholder:

    Goods placeholder

    The data attributes specify where the good can be downloaded from by the SatoshiPay client once the payment has been successfully completed, which specific type of good is displayed, its price and other content type specific properties like length or size. See below for a detailed description of the data attributes for different content types.

    During page load placeholders will appear in a simplified form (grey boxes) to make them recognizable while the SatoshiPay widget is being initialized. Placeholder styling can not be modified by the surrounding website.

    Text

    Text Example

    <div class="satoshipay-placeholder"
        data-sp-type="text/html"
        data-sp-src="/paid-content/1.html"
        data-sp-id="558bcdbb1309c59725bdb559"
        data-sp-price="1000"
        data-sp-length="800"
    ></div>
    

    This tag type represents text or HTML code that is loaded into the web page via an AJAX call after successful payment.

    Data Attributes

    Data Attribute Required Description
    data-sp-type yes Content type (MIME), must be either text/html or text/plain for this type of digital good. See supported types.
    data-sp-src yes HTTP endpoint as absolute or relative URL, e.g. /paid-content/1.html.
    data-sp-id yes Unique identifier for the good in SatoshiPay's registry. Consists of a hex string, e.g. 558bcdbb1309c59725bdb559.
    data-sp-price yes Price of content in satoshis, e.g. 4000.
    data-sp-length no Number of content characters (excluding HTML tags and other invisible characters), e.g. 800. The length will be used to determine how much area the placeholder will cover. Default value: 500.

    Image

    Image Example

    <div class="satoshipay-placeholder-image"
        data-sp-type="image/png"
        data-sp-src="/paid-content/2.png"
        data-sp-id="558bcdbb1309c59725bdb560"
        data-sp-price="4000"
        data-sp-width="450"
        data-sp-height="300"
        data-sp-placeholder="/placeholders/2.png"
    ></div>
    

    This tag type represents an image that is loaded by injection of an img tag after successful payment.

    Data Attributes

    Data Attribute Required Description
    data-sp-type yes Content type (MIME), must start with "image/" for this type of digital good, e.g. image/png. See supported types.
    data-sp-src yes HTTP endpoint as absolute or relative URL, e.g. /paid-content/2.png.
    data-sp-id yes Unique identifier for the good in SatoshiPay's registry. Consists of a hex string, e.g. 558bcdbb1309c59725bdb559.
    data-sp-price yes Price of image in satoshis, e.g. 4000.
    data-sp-width yes Width of image in pixels, e.g. 450.
    data-sp-height yes Height of image in pixels, e.g. 300.
    data-sp-placeholder no Absolute or relative URL to placeholder/preview image. This will be displayed if the image has not been paid yet. E.g. /placeholders/2.png.

    Audio

    Audio Example

    <div class="satoshipay-placeholder-audio"
        data-sp-type="audio/mpeg"
        data-sp-src="/paid-content/5.mp3"
        data-sp-id="558bcdbb1309c59725bdb555"
        data-sp-price="4000"
        data-sp-autoplay="true"
        data-sp-length="28007040"
        data-sp-title="Podcast: Interview with Satoshi Nakamoto"
    ></div>
    

    This tag type represents an audio file that is displayed by injecting an audio tag after successful payment.

    Data Attributes

    Data Attribute Required Description
    data-sp-type yes Content type (MIME), must start with "audio/" for this type of digital good, e.g. audio/mpeg. See supported types.
    data-sp-src yes HTTP endpoint for audio as absolute or relative URL, e.g. /paid-content/5.mp3.
    data-sp-id yes Unique identifier for the good in SatoshiPay's registry. Consists of a hex string, e.g. 558bcdbb1309c59725bdb555.
    data-sp-price yes Price of audio file in satoshis, e.g. 4000.
    data-sp-autoplay no Value for automatic audio playback, where available. E.g. true, default: false.
    data-sp-length yes HTTP content-length i.e. file size of audio in bytes. This value is used to indicate the audio file size next to the audio payment button. E.g. 28007040.
    data-sp-title no Short title of audio file, e.g. Podcast: Interview with Satoshi Nakamoto. If no title is given, File will be used.

    Video

    Video Example

    <div class="satoshipay-placeholder-video"
        data-sp-type="video/mp4"
        data-sp-src="/paid-content/4.mp4"
        data-sp-id="558bcdbb1309c59725bdb562"
        data-sp-price="4000"
        data-sp-width="640"
        data-sp-height="360"
        data-sp-autoplay="true"
        data-sp-placeholder="/placeholders/4.png"
    ></div>
    

    This tag type represents a video that is displayed by injecting a video tag after successful payment.

    Data Attributes

    Data Attribute Required Description
    data-sp-type yes Content type (MIME), must start with "video/" for this type of digital good, e.g. video/mp4. See supported types.
    data-sp-src yes HTTP endpoint for video as absolute or relative URL, e.g. /paid-content/4.mp4.
    data-sp-id yes Unique identifier for the good in SatoshiPay's registry. Consists of a hex string, e.g. 558bcdbb1309c59725bdb559.
    data-sp-price yes Price of video in satoshis, e.g. 4000.
    data-sp-height yes Height of video in pixels, e.g. 360.
    data-sp-width yes Width of video in pixels, e.g. 640.
    data-sp-autoplay no Value for automatic video playback, where available. E.g. true, default: false.
    data-sp-placeholder no Absolute or relative URL to placeholder/preview image. This will be displayed if the video has not been paid yet. E.g. /placeholders/4.png.

    Download

    Download Example

    <div class="satoshipay-placeholder-download"
        data-sp-type="application/pdf"
        data-sp-src="/paid-content/3.pdf"
        data-sp-id="558bcdbb1309c59725bdb561"
        data-sp-price="4000"
        data-sp-length="835669"
        data-sp-title="Book: What's the Deal with Bitcoins?"
    ></div>
    

    This tag type represents a secure download link that is displayed after successful payment.

    Data Attributes

    Data Attribute Required Description
    data-sp-type yes Content type (MIME), must start with "application/" for this type of digital good, e.g. application/pdf. See supported types.
    data-sp-src yes HTTP endpoint for download as absolute or relative URL, e.g. /paid-content/3.pdf.
    data-sp-id yes Unique identifier for the good in SatoshiPay's registry. Consists of a hex string, e.g. 558bcdbb1309c59725bdb559.
    data-sp-price yes Price of download in satoshis, e.g. 4000.
    data-sp-length yes HTTP content-length i.e. file size of download in bytes. This value is used to indicate the download size next to the download link. E.g. 835669.
    data-sp-title no Short title of download, e.g. Research Report 2016. If no title is given, File will be used.

    Retrieving Goods

    The merchant needs to provide public endpoints to allow the SatoshiPay widget to retrieve a good once it has successfully been paid for. The URL of an endpoint is defined as the data-sp-src attribute in the HTML tag.

    In the example, assuming the special HTML tags are defined in https://example.org/index.html, the data-sp-src attribute has been set to /satoshipay-content/5 (another possibility would be the absolute URL https://example.org/satoshipay-content/5).

    Content delivery for text, images, audio files, videos and downloads needs to be supported.

    Request Format

    Example Request

    curl https://example.org/satoshipay-content/5?paymentReceipt=eyJleHAiOjE1MDM1NzY4NDksIml0byI6IjAyZmNmZWNiZGFiMTExMmY0MjRiYzc2MTVmZDY2NjkzNzBhMjc3Njg1MjgxMjc3MWM2YWQ1Y2RmZTU3MTgzNDNkNSIsImp0aSI6ImNRNkROa1dUdjU3NGVLb2NoQnZlZWFtRzY2WE9lSUx4In0.13c5d97f6ac3b0d2412962437066ca22ada3cafad1aefad85a2e261a98b2ee14e0ca8f3c7772c78fd8fed9cfb0b51b4b4c154c078a1a0b36a5c19185c84b6281
    
    var request = require("request");
    request({
      url: "https://example.org/satoshipay-content/5",
      qs: {
        paymentReceipt: "eyJleHAiOjE1MDM1NzY4NDksIml0byI6IjAyZmNmZWNiZGFiMTExMmY0MjRiYzc2MTVmZDY2NjkzNzBhMjc3Njg1MjgxMjc3MWM2YWQ1Y2RmZTU3MTgzNDNkNSIsImp0aSI6ImNRNkROa1dUdjU3NGVLb2NoQnZlZWFtRzY2WE9lSUx4In0.13c5d97f6ac3b0d2412962437066ca22ada3cafad1aefad85a2e261a98b2ee14e0ca8f3c7772c78fd8fed9cfb0b51b4b4c154c078a1a0b36a5c19185c84b6281"
      }
    }, callback);
    

    The endpoint will be called with a GET request that has the following query parameters:

    Query Parameter Description
    paymentReceipt Receipt for payment. This parameter should be used by the endpoint to authenticate the request (see authentication below).

    Authentication

    Authentication is implemented on the merchant's HTTP endpoint without connecting to the SatoshiPay API using JSON Web Token standard (RFC 7519). It is done by verifying value of the query parameter paymentReceipt, which consists of Base64 encoded payload and signature split by a dot.

    Example URL

    https://example.org/satoshipay-content/5?paymentReceipt=eyJleHAiOjE1MDM1NzY4NDksIml0byI6IjAyZmNmZWNiZGFiMTExMmY0MjRiYzc2MTVmZDY2NjkzNzBhMjc3Njg1MjgxMjc3MWM2YWQ1Y2RmZTU3MTgzNDNkNSIsImp0aSI6ImNRNkROa1dUdjU3NGVLb2NoQnZlZWFtRzY2WE9lSUx4In0.13c5d97f6ac3b0d2412962437066ca22ada3cafad1aefad85a2e261a98b2ee14e0ca8f3c7772c78fd8fed9cfb0b51b4b4c154c078a1a0b36a5c19185c84b6281
    
    PAYLOAD="eyJleHAiOjE1MDM1NzY4NDksIml0byI6IjAyZmNmZWNiZGFiMTExMmY0MjRiYzc2MTVmZDY2NjkzNzBhMjc3Njg1MjgxMjc3MWM2YWQ1Y2RmZTU3MTgzNDNkNSIsImp0aSI6ImNRNkROa1dUdjU3NGVLb2NoQnZlZWFtRzY2WE9lSUx4In0"
    SIGNATURE="13c5d97f6ac3b0d2412962437066ca22ada3cafad1aefad85a2e261a98b2ee14e0ca8f3c7772c78fd8fed9cfb0b51b4b4c154c078a1a0b36a5c19185c84b6281"
    

    http://example.org/path?paymentReceipt=${payload}.${signature}

    Query Parameter Description
    payload Payload describes the user and expiration time.
    signature Signature is SHA256 hash of concatenated payload and good's sharedSecret known only by the merchant.

    Payload

    payload is a Base64 encoded JSON structure allowing to identify to whom the receipt was issued to and defining time when it expires.

    Example payload

    {
        "ito": "02fcfecbdab1112f424bc7615fd6669370a2776852812771c6ad5cdfe5718343d5",
        "exp": 1503576849,
        "jti": "cQ6DNkWTv574eKochBveeamG66XOeILx"
    }
    
    Field Name Description
    jti JWT ID Case sensitive unique identifier of the token.
    ito Issued To Identifies a user to whom the receipt was issued to.
    exp Expiration time Expiration time on which the payment receipt MUST NOT be accepted for processing.

    Validating request

    Validation procedure

    validate () {
        sharedSecret=$1
        paymentReceipt=$2
    
        receipt=(${paymentReceipt//./ })
        payload=$(echo "${receipt[0]}=" | base64 -D )
        signature=${receipt[1]}
        hash=$(echo -n "$sharedSecret$payload" | openssl dgst -sha256)
        exp=$(echo -n "$payload" | grep -oE '"exp":\d+,' | grep -oE '\d+')
        now=$(date +%s)
    
        [[ "$signature" == "$hash" && "0$exp" > "0$now" ]]
    }
    
    function validate (sharedSecret, paymentReceipt) {
      const receipt = paymentReceipt.split('.')
      const payload = base64url.decode(receipt[0])
      const signature = receipt[1]
      const hash = SHA256(payload + sharedSecret).toString()
    
      return (hash === signature && payload.exp > new Date().getTime())
    }
    

    Validating paymentRecepit means verifying the signature and expiration time. Signature is a SHA512 hash of Signature is the SHA256 hash of concatenated payload and good's sharedSecret known only by merchant.

    Merchant is responsible for generating unique sharedSecret for every good and storing it in his own database. Determining the sharedSecret value for a particular request should be done based on the good URL.

    Response Format

    Example Response

    HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    
    <strong>OH HAI!</strong> You've <em>nanopaid</em> me.
    

    The response needs to have HTTP status 200 set and contain the correct Content-Type header for the digital good. In most cases simply passing on the MIME media type returned by the file system should be sufficient, but make sure to check the list of content types that are supported.

    The HTTP header is followed by the content of the digital good, for example HTML code.

    Cross-Domain

    Required Headers

    Access-Control-Allow-Origin: *
    

    If you are serving digital goods from a different hostname the website containing SatoshiPay widget is served from, you need to work around the same-origin policy by adding these headers to your response:

    Range Requests

    Standard Response Header

    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Content-Length: 1000
    

    Partial Content Response Header

    HTTP/1.1 206 Partial Content
    Accept-Ranges: bytes
    Content-Length: 500
    Content-Range: bytes 0-499/1000
    

    For goods with a larger file size it is recommended to process HTTP range requests and serve partial content. This will allow browsers and download managers to resume a transfer or to transfer file segments in parallel.

    To make skipping to a certain position (seeking) in an audio file or video possible, support for range requests is required. Most browsers or players won't allow seeking if the HTTP source does not support partial content.

    We will publish sample digital goods servers written in PHP and Node with support for range requests soon. Contact us if you would like to get early access.

    Content Types

    SatoshiPay uses the MIME media type standard to identify the content of digital goods. Media types (also "content types") influence the way digital goods are retrieved and displayed. Here is a complete list of supported types.

    Text

    Image

    Audio

    Video

    Download