/decentrapay

Maker DAI payment processor

Primary LanguageJavaScriptMIT LicenseMIT

Decentrapay is an open-source payment processor which allows you to receive stablecoin tokens for payments.

Motivation

The goal of the project is to provide merchants with a decentralized, trustless solution to accept payments on the Ethereum blockchain.

Features

  • Direct P2P payments
  • No volatility risk as stablecoins are tied to fiat
  • Complete control over private keys
  • No middleman
  • REST API for managing invoices
  • Web interface for accessing invoices
  • A tool for managing generated wallets and forwarding payments

Requirements

  • Node v12 or newer
  • Access to the Ethereum network

Installation

Run the below commands:

git clone https://github.com/defisapiens/decentrapay.git
cd decentrapay
npm install

Don't forget to update local reposotory regularly to catch up with latest updates

git pull origin master
npm install

Configuration

Decentrapay needs to connect to the Ethereum network to process transactions. You have two options:

  • Connect to a locally running Ethereum node (geth or parity)
  • Use a third-party node service provider such as Infura

Open config/default.cson in a text editor and make necessary changes:

  1. If you are using an external node provider, update the provider section
provider:
  type: "rpc"
    uri: "http://localhost:8545" # replace with an endpoint URL from an external provider
  1. Change the apiKey to some unique string. The API key is used to post invoices to Decentrapay.

Running Decentrapay

To run the server in development mode, use the following command:

    npm run dev 

For production mode:

    npm run build
    npm start

API

Invoice object has the following properties:

  • apiKey - The API key to verify that the invoice creator is trusted (it is not stored in the database)
  • currency - Currency of the invoice. DAI,USDT,TUSD,USDC are supported at the moment. (optional)
  • merchant - The information about the merchant (optional)
    • name - The merchant’s name
    • address - The address to be displayed in the invoice
  • items - an array containing the invoice items. Decentrapay calculates totalAmount for all items and stores it with the invoice.
    • description - item description
    • quantity - number of units to be purchased (optional, default is 1)
    • amount - the unit cost
  • metadata - contains arbitrary data which is passed back to the app via the callback (see below). (optional)
  • expires - a timestamp until the invoice is valid (optional, default is 24 hours after the invoice was created)
  • callbacks - specifies where Decentrapay server should send a POST request containing token and metadata for notifying the app that the payment occurs.
    • token - a secret token to verify that the callback is originated from Decentrapay server
    • paid
      • url - where POST request should be sent to

Invoices can be created by sending a POST request to the /api/v1/invoice endpoint

An example with curl (replace API_KEY with the apiKey from the config file):

    curl http://localhost:8000/api/v1/invoice --header "Content-Type: application/json" -X POST -d '{"apiKey":"API_KEY",currency:"DAI","items":[{"description":"My item","amount":1}]}'

The backend will create a new invoice record and return its id

    {"invoiceId":"bfuWuYgRs"}

The invoice can be viewed in a browser at http://localhost:8000/invoice/bfuWuYgRs

Decentrapay invoice

Also, the invoice record can be accessed via REST API:

    curl http://localhost:8000/api/v1/invoice/bfuWuYgRs


    {"deposit":{"_id":"xm-8-8lThd","address":"0xE6F2392Fe8ED75f684cb93fA0e278f0E404a8522"},"_id":"bfuWuYgRs","items":[{"description":"item #1","amount":1}],"totalAmount":1,"paidAmount":0,"created":1548735086893,"state":"pending","__v":0}

Upon creation, an invoice gets linked with a deposit address generated by DecentraPay server. Private keys are stored in the local database in plain text format.

Newly created invoices have pending state. After an invoice is paid its state will be changed to confirming. Then the server waits for the number of blocks specified in the configuration as minConfirmations (default is 1) and if thereafter the invoice balance is not less than totalAmount, the server changes the invoice state to paid and notifies the app via callback that the payment was done. The app should return HTTP code 200 to acknowledge that the invoice was processed. Then the invoice status is changed to closed.

If the invoice was not paid on time, as configured by the expires property, its status will be set to expired and no callbacks will be called thereafter.

Maintainence

Collecting payments

Until it is possible to pay for gas with tokens on the Ethereum network, collecting and forwarding payments can be a bit challenge because generated wallets need gas in order to be able to transfer DAI. For that purpose, Decentrapay includes a tool named wallets that funds wallets with small amounts of ETH if needed and then transfer tokens out.

Example command usage:

npm run wallets --  --fundamount 0.001 --collect <YOUR ETHEREUM ADDRESS> --privatekey 4e4a0db6ee08f21c68923f9a068a40c97769796fc88232c465a932d102a6eab4

the collect parameter specifies the destination address for collected payments and the privatekey is a private key of any account with small amount of ETH (it can be a key exported from MetaMask, for example). In the result, each non-empty wallet that linked to a closed invoice will be funded with 0.001 ETH if needed and then DAI tokens be transferred out to the specified address. Released wallets will be then re-used by the backend because there is a high chance they still have gas.

IMPORTANT: Be careful when using this tool - any mistake may result in lost funds. Do not use accounts with large amounts of ETH.

TODO

  • Adding a project logo
  • Point-of-Sale mode

CREDITS

  • Inspired by Baron project