Introductory guide: rewarding points app made with NEM/PHP/Stripe

Hello, nem community,
we at Familypoints.io have chosen NEM as our blockchain solution for our project and very excited about this.

As a way to contribute back to the community, we decided to write a few introductory articles on NEM and how to use it to build PHP web app for rewarding customers for purchases. This is one of our core features we introduce on our platform.

Read the article

Rewards points platform made simple: NEM + Laravel 5.5 + Stripe. Part I.

Prerequisite

In this tutorial, you will learn how to use NEM blockchain to reward customers for purchases (think of Starbucks Rewards). We will integrate NEM with Stripe with Laravel Framework(v5.5) and build a rewarding points e-commerce app.

You should be familiar with making apps with Laravel framework and you need a fresh Laravel installation in order to feel comfortable reading this tutorial.

Also worth mentioning, we will utilize NIS (NEM Infrastructure Server) API in this tutorial and each request we will make manually, without any UI clients/wallets. By this, we will fully understand how API works and how to use it. In order to do this, you need Httpie tool to be installed.

The article is divided into two parts:

  • In Part-I, we talk about NEM in general and how to prepare NEM infrastructure for our use case.
  • In Part-II, we go down to coding and implementing our apps with Laravel framework.

Intro

When I first joined NEM community and met the NEM foundation team I was impressed by how energized, friendly and active they were. It is a community of open-minded and proactive people who drive the Idea of NEM blockchain.

But the feeling was not new, I felt the same when I was first introduced to another online community of developers - Laravel Framework community. These two have much in common - fresh idea, advanced technology, low barriers for newcomers, friendly support from other members and wide adoption.

Now that I am part of two worlds, Nem and Laravel, I decided to write an app which illustrates how easy it is to build a web service with Laravel, which uses blockchain technology powered by NEM.

What we are going to build

For the last 3 years, I was a part of the IT team in Babystep.tv where we were building services for parents. And now we have launched a new project - Family Points Platform which allows parents to spend more on kids education by rewarding them for being active on the platform.

While the platform has quite a few features, the core one is returning a part of the spent money back to the parent in a form of Points. Having a wide choice of maternity and baby products available on the platform, parent spends money on these quality products and we give her rewards in a form of points.

Ok, now we know that our points will be based on the blockchain implementation by NEM, the app will be based on Laravel framework and we have to choose which payment gateway to use for accepting money.

On different markets, there are different players, one the most developer friendly and established ones which support many payment methods is Stripe. Since our core market is China, it is very important that Stripe supports Alipay and WeChat Pay, these two dominate the China market.

The architecture

Let’s review the architecture of the system we’re going to build. The whole system consists of a few parts:

Architecture overview

  • Laravel app
    It is a website with HTML pages and a business logic which controls users, payments, goods, points etc. It resides on server A, has public access to the Internet and handles user’s requests.
    It has a set of smart contracts which control the money flow and rewarding points circulation.
    It communicates with Stripe service and processes simple charges.

  • Co-signer Laravel app
    This is an important additional security measure (if you are familiar with a 2-factor authentication, this is most like it). It is used to co-sign valid transactions. The app resides on a dedicated server B with no direct connection with an E-commerce app. In case the e-commerce app is compromised (hacked) we can prevent funds allocated on our wallets from being stolen.

    The co-signer listens to pending transactions, reviews them, and validates if they look legitimate and then signs a transaction on the NEM blockchain.

  • NEM Blockchain
    The network of NEM nodes is spread across the globe. It offers HTTP API and we consume it as any other service.
    To use the public blockchain we need XEMs to be loaded on our account because each transaction on the chain requires a fee being paid. This is why we need to protect our funds.

    I suggest you read this technical overview of NEM to get deeper insights. If you interested in more details about the NEM internals - take a look at this blog post.

  • Stripe service
    Remote service which handles payments and offers unified HTTP APIs. It accepts requests for payments, processes it and then notifies Laravel app about results.

    Upon successful payment, Laravel app executes a proper smart contract which rewards a payer with points.

Private keys distribution

There are four accounts being used to manage the platform (each has private and public keys). All of them are spread across two servers:

  • E-commerce App, Server A
    This server is publicly available.
  • Co-signer App, Server B
    This server is isolated and has public access. It can only interact with NEM blockchain and shared data storage (also accessible by Ecommerce App).

4 accounts have different purposes:

  • Account_1. Keys are stored on server A.
    Initiates points transfers on behalf of multisig Account_2
  • Account_2. Keys are stored on server A.
    This is a multisig account (2-of-3) which stores XEMs and an initial amount of Points. The only way to transfer assets is by initiating a transaction which must be confirmed by cosignatories.
  • Account_3. Keys are stored on server B.
    This account is a cosignatory for Account_2.
  • Account_4. Keys are stored on server B.
    This account is a cosignatory for Account_2.

There are 3 cosignatories for an Account_2 and two signs are required in order to commit a transaction, which makes this account a 2-of-3. 3 co-signers are needed to make the system safe. Account_3 and Account_4 stores its keys on a dedicated server and one of them co-signs requested transactions.

In case of compromising private keys of Account_1 and Account_2 we still remain control over Account_2 assets. Because the rest of co-signers’ keys are located on another server.

NEM smart contracts

NEM platform does not support “on-chain” smart contracts. Unlike Ethereum with smart contracts published directly on the blockchain, NEM offers secure APIs which can be consumed by “off-chain” smart contract.

Our system has several smart contracts to interact with NEM:

  • Create multisig accounts for each new customer
  • Transfer points to customers on each successful purchase
  • Listen and verify pending transaction. Co-sign valid ones.

Preparing NEM test node

To interact with a NEM blockchain you need a running node which has APIs and responds to your requests. Either you will run a node locally or use the existing network of nodes. For the purpose of this tutorial we will use existing node available at https://nem-test.familypoints.io:7891, it is connected to the test NEM network.

:::info
A word of Notice
It is discouraged to interact with a remote Node. For the best security run a local node and interact with it directly.
:::

For a production mode, you will need your own node running somewhere on your server, to learn how to launch a node.
What you need to do:

  1. Install 64-bit version of JAVA.
  2. Download and extract the latest release from here:
    wget http://bob.nem.ninja/nis-0.6.95.tgz
    sudo tar xzf nis-0.6.95.tgz
    
  3. Edit config file at nis/config.properties.
  4. Run the NIS node:
    ./nix.runNis.sh
    
  5. Test it is accessible:
    http -b https://nem-test.familypoints.io:7891/status
    
    {
        "code": 5,
        "message": "status",
        "type": 4
    }
    
    Code 5 means node is still syncing. In a while it will be fully operational.

Preparing 4 accounts

We need to make 4 accounts as explained above. It is simple to generate a new account by just sending a GET request:

http -b https://nem-test.familypoints.io:7891/account/generate

{
    "address": "TDBEUBX6SJDSO64NDAU3QMHOCAPWLFGYD4KCOV3E",
    "privateKey": "54cce7c2422c8307488a4dd2ae6ac22fb0e2e2c9d3ca05081312020fb7882a68",
    "publicKey": "705803b12a02b8e32a4d4f1d8c8c3d0ddb0bd87fbc1dca30ebbd6cc12f59530d"
} 

Write down 4 generated keys and addresses:

Account_1
{"privateKey":"...","address":"...","publicKey":"..."}

Account_2
{"privateKey":"...","address":"...","publicKey":"..."}

Account_3
{"privateKey":"...","address":"...","publicKey":"..."}

Account_4
{"privateKey":"...","address":"...","publicKey":"..."}

Converting to a multisig account

Now, Account_2 must be converted to a multisig account. These are the steps to do this:

  1. Load account with 34 XEMs (this is a fee for a multisig conversion)
  2. Initiate a conversion transaction.
    As of now, NEM does not support batch transactions, so we cannot commit both of these actions in one transaction. But upcoming “Catapult” release will solve this for us.

How to load test XEMs to Account_2? The easiest way is to utilize existing faucets. For example, this one: http://test-nem-faucet.44uk.net/. Visit the page and send about 40 XEMs to account’s address.

Now let’s send multisig convertion request. We need to prepare a complex body, which includes different types of data. I added a console command which will generate the json data for us. Source code is available here. Call the command like this:

php convertToMultisigJSON.php "account2_publickKey" "account2_privateKey" "account1_publickKey" "account3_publickKey" "account4_publickKey"

Now pass the output of this file to the NIS like this:

php convertToMultisigJSON.php "account2_publickKey" \
"account2_privateKey" "account1_publickKey" "account3_publickKey" \
"account4_publickKey" | http https://nem-test.familypoints.io:7891/transaction/prepare-announce --json

# if went well, the result should look like this
{
    "code": 1,
    "innerTransactionHash": {},
    "message": "SUCCESS",
    "transactionHash": {
        "data": "1a9..."
    },
    "type": 1
}

Now we have one multisig account and 3 co-signers in place.
Here is the perfect time to send to this fresh account more XEMs, so it can send assets to other customers.

Creating points asset

Rewarding points are assets that we send to customers for purchases. On NEM blockchain assets called mosaics and reside under specific namespaces (just like files in folders).

We need to provision our root namespace and create a mosaic.

Provisioning a namespace

Namespace as a container for your assets. Let’s create one with name “my-company”.

Pass the output of PHP script to the NIS like this:

php provisionNamespaceJSON.php "account1_publickKey" "account1_privateKey" \
"my-company" | http https://nem-test.familypoints.io:7891/transaction/prepare-announce --json

# if went well, the result should look like this
{
    "code": 1,
    "innerTransactionHash": {},
    "message": "SUCCESS",
    "transactionHash": {
        "data": "..."
    },
    "type": 1
}

Creating a new mosaic

Mosaic is an actual asset - rewarding points. It has a name, a description, divisibility and some other flags.
Let’s define our asset like this (PHP script):

php createMosaicJSON.php "account1_publickKey" "account1_privateKey" "my-company" "points" "Rewarding points" "6" "1000" | http https://nem-test.familypoints.io:7891/transaction/prepare-announce --json

# if went well, the result should look like this
{
    "code": 1,
    "innerTransactionHash": {},
    "message": "SUCCESS",
    "transactionHash": {
        "data": "..."
    },
    "type": 1
}

Now we prepared our NEM infrastructure:

  • we have live running NIS node
  • we have created and secured multisig account for storing assets
  • we have provisioned namespace and asset

Conclusion

NEM offers unique APIs which are easily integrated into any existing app. It is a matter of reading a documentation to start using NEM. In this tutorial, we described and exposed an app which rewards customers with points for purchases. This is done in a secured manner and powered by blockchain technology.

Unfortunately, there is lack of production-ready PHP wrappers for NEM API. I believe this is a matter of time.

Currently available libraries:

I hope you learned a bit about NEM and now ready to explore more.

Next article

In the next article (part II) we will cover:

  • Co-signer App. Listening to pending transactions and co-signing them.
  • E-commerce App. Making payments with Stripe and transferring rewarding points.

Links:

8 Likes