One-Step Payment

Overview

The One-Step Payment (OSP) is the simplest method for purchases using AppCoins. To implement it, the developer must create a URL with the payment information (see picture below).
Visit the easy integrations page for more information.

641

One Step Payment flow

Process

  1. Create the URL to start the purchase flow. The URL should follow this structure;
  2. Use the URL to make a system call;
  3. AppCoins wallet will communicate with our services to process the payment;
  4. Once the purchase is concluded, if you're taking the backend route, our server will notify the app’s services with the details. To see more about the server's notification, click here.
  5. The app’s server should deliver the purchased item, for the backend route, or the app should validate and give the item locally, for the no-backend route.

Implementing OSP in a native Android application

There are 2 ways to implement OSP in your app:

Implementation with server-side validation is safer since, in this way, every validation is performed server-side and if the URL is changed/damaged, our services will reject it.

Implementation without server-side validation is simpler but not as safe. The process is similar to Google Billing without server-side check, since the entire validation is in the APK, meaning that the value of the purchases can be manipulated by people with reverse engineering skills.

If you opt to implement OSP without server-side validation, you undertake a maximum limit of 500 completed transactions every 30 days to prevent any type of fraud.

Implementing OSP in Unity

The advised way to implement OSP in unity is to create a C# MonoBehavior script that will have the OSP flow logic and can be associated with the IAP buttons.

Just like in regular Android there are two ways of implementing OSP:

OSP URL Structure

Scheme: https
Host: apichain.catappult.io
Path: /transaction/inapp
Query string arguments: value, currency, to, product, domain, data, callback_url, reference, signature
Example:

https://apichain.catappult.io/transaction/inapp?value=11&currency=USD&domain=com.appcoins.trivialdrivesample&product=sword.001

🚧

Warning!

Previously there was a "to" argument where the destination wallet address would be specified. This argument is no longer needed and was removed from this example.

Query String Arguments details

ParameterTypeDescription_of_fieldStaticOptionalExample
value*DoubleThe value of the chosen product (if no currency is set it is considered APPC)NN11.5
currencyStringThe currency in which the value is sent, if no currency is sent it is considered APPC (AppCoins).NYUSD or EUR
product*StringThe id of the item being bought.
It can only have lowercase letters, numbers, underscores (_) and periods (.)
YNsword.001
domain*StringThe application id, also known as package name.YNcom.appcoins.trivialdrivesample
dataStringAdditional information to be sent if needed.NYAwesome Sword
callback_urlStringThe developer's URL to be called after the transaction is completed.
It must be URL encoded.
NYhttps://mygamestudio.co/appcoins?out_trade_no=1234
must be encoded to
https%3A%2F%2Fmygamestudio.co%2Fappcoins%3Fout_trade_no%3D1234
order_referenceStringUnique identifier of the transaction created by the developer. (Cannot be used for different purchases)NYXYZ98880032
signatureStringThe Hexadecimal string of the signed URL in order to be validated. For more details see section Create URL (backend).
The signature must be lowercase.
NY49bc6dac9780acfe5419eb16e862cf096994c15f807313b04f5a6ccd7717e78e

* mandatory fields

Payment Notification

If the developer provides a callback URL, our purchase service triggers a notification whenever there is a valid purchase. In order to use this service you must:

After the URL is called and the payment is processed our services make a request to the callback URL that follows the structure specified in Request to callback URL (to see more about this, click here). For this reason, the developer needs to prepare the server to handle this request and finally validate if the request did come from Catappult.

📘

For a fully working sample, you can check the following link: https://github.com/Catappult/appcoins-server-validator

Request to callback URL

Method: Post
URL: The provided URL
Body: signature, transaction
Content type: Json
Response code: 200

❗️

Response code

It is important that your service return 200 as status code so we acknowledge you did receive the notification successfully.

Body example

{
  "signature": "62747e2bd871b38794edf8e7e27fc525f523be4955beeb2467ba8617d10ef1ff3c39eac5c75a52c8ebc0badefec32a84616f26ebc0213fa86604567c218b74931b",
  "transaction": "{\"uid\":\"2DtyvTOSShc1xT9C\",\"domain\":\"com.appcoins.trivialdrivesample\",\"product\":\"gas\",\"reference\":\"XYZ98880032\",\"status\":\"COMPLETED\",\"added\":\"2020-05-04T10:19:44+00:00\",\"modified\":\"2020-05-04T10:19:44+00:00\",\"price\":{\"currency\":\"APPC\",\"value\":\"1\",\"appc\":\"1\"}}"
}

Body structure

Details about parameters present at the root of the json object sent when calling callback_url:

TypeNameDescriptionSchemaExample
Bodysignature(Deprecated)
Notification signature based on transaction parameter
string0x7b87a3c4dd63bee43d4c88
BodytransactionTransaction resource in jsonstring

Signature

Deprecated: This argument is no longer used.

Transaction parameter fields

This parameter is a json structured string that should be parsed to get the information about the purchase itself.

NameDescriptionSchemaExample
uidUnique ID for transaction resourcestring2DtyvTOSShc1xT9C
domainPackage namestringcom.appcoins.trivialdrivesample
productProduct name (aka SKU)stringsword.001
referenceUnique identifier of the transaction created by the developer.stringXYZ98880032
statusTransaction statusstringCOMPLETED or CANCELED or FAILED
addedTransaction added timestmapstring2020-04-18T06:15:18+00:00
modifiedTransaction modified timestmapstring2020-04-18T07:17:19+00:00
typeType of transactionstringINAPP_UNMANAGED
price.appcTransaction price in AppCoinsstring115
price.currencyTransaction price currency (used by user to perform the purchase)stringUSD, APPC, EUR, etc
price.valueTransaction price valuestring11.5
price.usdTransaction price in USDstring4.99

Transaction API

UID

Method: GET
Scheme: https
HOST: api.blockchainds.com
Path: /broker/8.20200101/transactions/{uid}
Ex:

https://api.blockchainds.com/broker/8.20200101/transactions/2DtyvTOSShc1xT9C

Response:

{
    "uid": "2DtyvTOSShc1xT9C",
    "domain": "com.appcoins.trivialdrivesample",
    "product": "gas",
    "wallet_from": "0xa43748bf498d7070d05d4fde042c51c780ce71b9",
    "country": "PT",
    "type": "INAPP_UNMANAGED",
    "method": "appcoins_credits",
    "reference": null,
    "hash": "0x234e3c2407680ffe07d4f1bb7bc5c773085cd4ca723669a0473777ceeaabab95",
    "origin": "BDS",
    "status": "COMPLETED",
    "added": "2020-05-04T10:19:45+00:00",
    "modified": "2020-05-04T10:19:45+00:00",
    "gateway": {
        "name": "appcoins_credits"
    },
    "metadata": null,
    "price": {
        "currency": "APPC",
        "value": "1",
        "appc": "1",
        "usd": null
    }
}

Hash

Method: GET
Scheme: https
HOST: api.blockchainds.com
Path: /broker/8.20200101/transactions
Query parameters: hash
Ex:

https://api.catappult.io/broker/8.20200101/transactions?hash=0x234e3c2407680ffe07d4f1bb7bc5c773085cd4ca723669a0473777ceeaabab95

Response:

{
    "next": null,
    "items": [
        {
            "uid": "2DtyvTOSShc1xT9C",
            "domain": "com.appcoins.trivialdrivesample",
            "product": "gas",
            "wallet_from": "0xa43748bf498d7070d05d4fde042c51c780ce71b9",
            "country": "PT",
            "type": "INAPP_UNMANAGED",
            "method": "appcoins_credits",
            "reference": null,
            "hash": "0x234e3c2407680ffe07d4f1bb7bc5c773085cd4ca723669a0473777ceeaabab95",
            "origin": "BDS",
            "status": "COMPLETED",
            "added": "2020-05-04T10:19:45+00:00",
            "modified": "2020-05-04T10:19:45+00:00",
            "gateway": {
                "name": "appcoins_credits"
            },
            "metadata": null,
            "price": {
                "currency": "APPC",
                "value": "1",
                "appc": "1",
                "usd": null
            }
        }
    ]
}