From c7af637bda0de8bc6b24c25859ec08dba8187b5e Mon Sep 17 00:00:00 2001 From: OdinsPlasmaRifle Date: Mon, 8 Jul 2019 20:06:47 +0200 Subject: [PATCH 01/19] Added initial files --- .gitignore | 6 + .gitmodules | 3 + README.md | 1 + config.yaml | 21 +++ content/_index.md | 5 + content/checkout/_index.md | 10 ++ content/checkout/core-resources/_index.md | 6 + content/checkout/core-resources/accounts.md | 72 ++++++++++ .../checkout/core-resources/transactions.md | 79 +++++++++++ content/checkout/core-resources/users.md | 71 ++++++++++ content/checkout/get-started/_index.md | 6 + content/checkout/get-started/introduction.md | 34 +++++ content/checkout/get-started/quick-guide.md | 134 ++++++++++++++++++ content/checkout/integration-guide/_index.md | 6 + .../integration-guide/authentication.md | 38 +++++ content/checkout/integration-guide/balance.md | 78 ++++++++++ .../checkout/integration-guide/overview.md | 37 +++++ content/checkout/integration-guide/payment.md | 122 ++++++++++++++++ content/checkout/usage/_index.md | 6 + content/checkout/usage/authorization.md | 22 +++ content/checkout/usage/errors.md | 41 ++++++ content/checkout/usage/events.md | 42 ++++++ content/checkout/usage/filters.md | 33 +++++ content/checkout/usage/idempotency.md | 24 ++++ content/checkout/usage/pagination.md | 22 +++ static/images/favicon.png | Bin 0 -> 4905 bytes static/images/hero.png | Bin 0 -> 7511 bytes static/images/logo.png | Bin 0 -> 63847 bytes 28 files changed, 919 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 README.md create mode 100644 config.yaml create mode 100644 content/_index.md create mode 100644 content/checkout/_index.md create mode 100644 content/checkout/core-resources/_index.md create mode 100644 content/checkout/core-resources/accounts.md create mode 100644 content/checkout/core-resources/transactions.md create mode 100644 content/checkout/core-resources/users.md create mode 100644 content/checkout/get-started/_index.md create mode 100644 content/checkout/get-started/introduction.md create mode 100644 content/checkout/get-started/quick-guide.md create mode 100644 content/checkout/integration-guide/_index.md create mode 100644 content/checkout/integration-guide/authentication.md create mode 100644 content/checkout/integration-guide/balance.md create mode 100644 content/checkout/integration-guide/overview.md create mode 100644 content/checkout/integration-guide/payment.md create mode 100644 content/checkout/usage/_index.md create mode 100644 content/checkout/usage/authorization.md create mode 100644 content/checkout/usage/errors.md create mode 100644 content/checkout/usage/events.md create mode 100644 content/checkout/usage/filters.md create mode 100644 content/checkout/usage/idempotency.md create mode 100644 content/checkout/usage/pagination.md create mode 100644 static/images/favicon.png create mode 100644 static/images/hero.png create mode 100644 static/images/logo.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3bee02f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Hugo default output directory +/public +resources/_gen/ +.env + +*.DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..511c729 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "themes/hexon-hugo-theme"] + path = themes/hexon-hugo-theme + url = https://github.com/OdinsPlasmaRifle/hexon-hugo-theme.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b69328 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# docs diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..eb1b5a2 --- /dev/null +++ b/config.yaml @@ -0,0 +1,21 @@ +baseURL: "https://plue.io" +languageCode: "en-us" +title: "Documentation" +theme: "hexon-hugo-theme" + +params: + logoUrl: http://plue.io + logoImage: /images/logo.png + heroImage: /images/hero.png + favicon: /images/favicon.png + + primaryColor: "#002d6d" + secondaryColor: "#ff2852" + + extraNavItems: + - title: Log in + url: https://wallet.plue.io + + extraFooterItems: + - title: Log in + url: https://wallet.plue.io \ No newline at end of file diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..f2aa1c7 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,5 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Documentation +description: Plue documentation +--- \ No newline at end of file diff --git a/content/checkout/_index.md b/content/checkout/_index.md new file mode 100644 index 0000000..60ebab5 --- /dev/null +++ b/content/checkout/_index.md @@ -0,0 +1,10 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Merchant checkout +description: Merchent checkout API documentation. +weight: 1 +linkTo: /checkout/get-started/introduction +references: + - title: Javascript SDK + url: https://www.npmjs.com/package/@pluewallet/plue +--- diff --git a/content/checkout/core-resources/_index.md b/content/checkout/core-resources/_index.md new file mode 100644 index 0000000..cd4cb16 --- /dev/null +++ b/content/checkout/core-resources/_index.md @@ -0,0 +1,6 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Core resources +description: Core resources of the platform. +weight: 3 +--- diff --git a/content/checkout/core-resources/accounts.md b/content/checkout/core-resources/accounts.md new file mode 100644 index 0000000..88b9fe0 --- /dev/null +++ b/content/checkout/core-resources/accounts.md @@ -0,0 +1,72 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Accounts +description: Account resources. +weight: 2 +--- + +### Object + +This object can be used to check the currency balances for a user before approving a transaction. + +The full account object with a single currency looks like: + +```json +{ + "name": "default", + "label": "Default", + "reference": "0000000000", + "primary": true, + "user": { + "id": "00000000-0000-0000-0000-000000000000", + "username": null, + "email": "joe@example.com", + "mobile": "+27840000000", + "first_name": "Joe", + "last_name": "Soap", + "profile": null + }, + "currencies": [ + { + "balance": 0, + "available_balance": 0, + "currency": { + "code": "USD", + "description": "United States dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "limits": [], + "fees": [], + "active": true, + "settings": { + "allow_transactions": true, + "allow_debit_transactions": true, + "allow_credit_transactions": true + }, + "archived": false, + "created": 1538573021547, + "updated": 1538573021547 + } + ], + "archived": false, + "created": 1538573021502, + "updated": 1538573021502 +} +``` + +### Endpoints + +To view an account or its currencies you can use the following endpoints. Keep in mind, accounts are always identified by their `reference`. + +section | type| URL | methods +---|---|---|--- +user | multiple | `https://api.plue.io/3/accounts/` | `GET`, `POST` +user | single | `https://api.plue.io/3/accounts//` | `GET`, `PUT`,`PATCH` +user | multiple | `https://api.plue.io/3/accounts//currencies/` | `GET`, `POST` +user | single | `https://api.plue.io/3/accounts//currencies//` | `GET`, `PUT`,`PATCH` + +### Usage + +Usage remains the same for all endpoints. Simply invoke one of the allowed HTTP methods with the correct `Content-Type` and a `Authorization` header. diff --git a/content/checkout/core-resources/transactions.md b/content/checkout/core-resources/transactions.md new file mode 100644 index 0000000..f79223e --- /dev/null +++ b/content/checkout/core-resources/transactions.md @@ -0,0 +1,79 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Transactions +description: Transaction resources. +weight: 3 +--- + +Transactions are a way to manage value on and between accounts in the Plue wallet. Every transaction can be either a `debit` or a `credit`. In simple terms `debit` reduces an account's balance and a `credit` increases an account's balance. A transfer can be thought of as a 2-step transaction where one user is debited and another is credited the required amount. This structure allows for easy verification of balances and can be used to back track to a specific point in time to discover what the balance was. + +Every transaction has a status that can be used to gauge the state of the transaction. The statuses are: + +status | description +---|--- +Initiating | processing the transaction insert +Pending | the transaction has passed all validation +Complete | the transaction has been applied to the account currency's balance. +Failed | the transaction and the balance have been reverted + +### Object + +Transactions are essentially logs of actions on an account balance. With this in mind, transactions contain information that can be used to identify who made the transaction, what the transaction was made on, and how the transaction impacted the account. + +A full transaction object looks like: + +```json +{ + "status": "success", + "data": { + "id": "00000000-0000-0000-0000-000000000000", + "tx_type": "credit", + "subtype": null, + "note": "", + "metadata": {}, + "status": "Pending", + "reference": null, + "amount": 500, + "fee": 0, + "total_amount": 500, + "balance": 0, + "account": "0000000000", + "label": "Credit", + "company": "plue_prod", + "currency": { + "description": "Rand", + "code": "ZAR", + "symbol": "R", + "unit": "rand", + "divisibility": 2 + }, + "source_transaction": null, + "destination_transaction": null, + "messages": [], + "fees": [], + "created": 1476691969394, + "updated": 1496135465287 + } +} +``` + +A debit transaction will look much the same as the above, except the `amount` will be a negative value and the `tx_type` will be `Debit`. + +On the other hand a transfer will have some additional information in the `source_transaction` or `destination_transaction` attributes. As stated previously, transfers are simply debits/credits themselves. So, if a transfer is made between two accounts 2 transactions will be created: + +1. A debit transaction reducing the balance of the sender. In addition the `destination_transaction` attribute will be populated with a pointer to the receiver transaction. +2. A credit transaction increasing the balance of the receiver. In addition the `source_transaction` attribute will be populated with a pointer to the sender transaction. + +### Endpoints + +section | type| URL | methods +---|---|---|--- +user | multiple | `https://api.plue.io/3/transactions/` | `GET`, `POST` +user | single | `https://api.plue.io/3/transactions//` | `GET`, `PUT`,`PATCH` +user | single | `https://api.plue.io/3/transactions/transfer/` | `POST` +user | single | `https://api.plue.io/3/transactions/debit/` | `POST` +user | single | `https://api.plue.io/3/transactions/credit/` | `POST` + +### Usage + +Usage remains the same for all endpoints in Plue. Simply invoke one of the allowed HTTP methods with the correct `Content-Type` and a `Authorization` header. diff --git a/content/checkout/core-resources/users.md b/content/checkout/core-resources/users.md new file mode 100644 index 0000000..43aa004 --- /dev/null +++ b/content/checkout/core-resources/users.md @@ -0,0 +1,71 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Users +description: User resources. +weight: 1 +--- + +### Object + +This object is returned together with the authentication token when the user logs in. The full user object looks like this: + +```json +{ + "id": "00000000-0000-0000-0000-000000000000", + "first_name": "Joe", + "last_name": "Soap", + "email": "joe@example.com", + "username": null, + "id_number": "", + "birth_date": "2000-01-01", + "profile": null, + "currency": { + "description": "Rand", + "code": "ZAR", + "symbol": "R", + "unit": "rand", + "divisibility": 2 + }, + "company": "plue_prod", + "language": "en", + "nationality": "ZA", + "metadata": null, + "mobile": "+27840000000", + "timezone": "Asia/Dhaka", + "verified": true, + "verification": { + "email": true, + "mobile": true + }, + "kyc": { + "updated": 1509539801040, + "status": "pending" + }, + "status": "pending", + "groups": [], + "permissions": [], + "created": 1464912953000, + "updated": 1464912953000, + "settings": { + "allow_transactions": true, + "allow_debit_transactions": true, + "allow_credit_transactions": true + }, + "last_login": null, + "archived": false +} +``` + +### Endpoints + +section | type| URL | methods +---|---|---|--- +auth | single | `https://api.plue.io/3/user/` | `GET`, `PUT`,`PATCH` +auth | single | `https://api.plue.io/3/auth/register/` | `POST` +auth | single | `https://api.plue.io/3/auth/login/` | `POST` +auth | single | `https://api.plue.io/3/auth/logout/` | `POST` + + +### Usage + +Usage remains the same for all endpoints. Simply invoke one of the allowed HTTP methods with the correct `Content-Type` and a `Authorization` header if required. diff --git a/content/checkout/get-started/_index.md b/content/checkout/get-started/_index.md new file mode 100644 index 0000000..51740c8 --- /dev/null +++ b/content/checkout/get-started/_index.md @@ -0,0 +1,6 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Get started +description: Get started with the platform. +weight: 1 +--- diff --git a/content/checkout/get-started/introduction.md b/content/checkout/get-started/introduction.md new file mode 100644 index 0000000..805a8a8 --- /dev/null +++ b/content/checkout/get-started/introduction.md @@ -0,0 +1,34 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Introduction +description: Introduction to the platform. +weight: 1 +--- + +The Merchant API allows you to integrate the Plue wallet into your existing checkout flow. + +### The API + +The API is organized around RESTful principles. There are 2 primary sections to the merchant API: + +#### Auth + +The auth section of the platform provides endpoints for handling authentication and other authorization related functions that are common to all users within the platform. + +Authentication endpoints do not require any specific permissions nor are they limited by any other access control. + +Some example endpoints are: + +* `/3/auth/register/` +* `/3/auth/login/` +* `/3/auth/logout/` + +#### User + +The user section of the platform API is designed for end-users. This set of endpoints only exposes a data set that is relevant to the user as an individual within the system. These endpoints can be exposed to end-users and were created to be used without any intermediary services or layers. + +Some examples endpoints are: + +* `/3/user/` +* `/3/accounts/` +* `/3/transactions/` \ No newline at end of file diff --git a/content/checkout/get-started/quick-guide.md b/content/checkout/get-started/quick-guide.md new file mode 100644 index 0000000..68ae5f7 --- /dev/null +++ b/content/checkout/get-started/quick-guide.md @@ -0,0 +1,134 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Quick guide +description: A quick guide to the platform. +weight: 2 +--- + +To get started with the API you have a couple options: + +1. You can choose to use the Plue supported JS SDK +2. Integrate the API manually in your choice of language. + +To use the the SDK check for you language in the "references list" in the sidebar. If you instead want to use a language that does not have a Plue supported SDK, a custom implementation should be trivial as the platform uses standard HTTP which is widely supported. + +### Using the API + +The easiest way to get started with the API is to use cURL to make a login request: + +``` +curl https://api.plue.io/3/auth/login/ + -X POST + -H "Content-Type: application/json" + -d '{"user": "joe@example.com", + "company": "plue_prod" + "password": "joe1234"}' +``` + + + +Once you have your own user you can replace the placeholder data in the example JSON object and then fire off the above request. If successful, you should get a response like this: + +```json +{ + "status": "success" + "data": { + "token": "{token}", + "user": { + "id": "00000000-0000-0000-0000-000000000000", + "first_name": "Joe", + "last_name": "Soap", + "email": "joe@example.com", + "username": "", + "id_number": null, + "birth_date": null, + "profile": null, + "currency": null, + "company": "plue_prod", + "language": "en", + "nationality": "CA", + "metadata": {}, + "mobile": "+00000000000", + "timezone": null, + "verified": false, + "status": "pending", + "kyc": { + "updated": 1509539801040, + "status": "pending" + }, + "verification": { + "email": true, + "mobile": true + }, + "groups": [ + { + "name": "test", + "label": "Test" + } + ], + "permissions": [], + "settings": { + "allow_transactions": true, + "allow_debit_transactions": true, + "allow_credit_transactions": true + } + "created": 1464912953000, + "updated": 1464912953000, + } + } +} +``` + +And there you have it, a successful login. The user was validated and authenticated on the platform and an authentication `token` returned. + + + +For example, you may want to get a list of accounts associated to the user: + +``` +curl https://api.plue.io/3/user/accounts/ + -X GET + -H "Authorization: Token {token}" + -H "Content-Type: application/json" +``` + +If you used the `token` you previously retrieved you should get a successful response containing a list of user accounts: + + +```json +[ + { + "name": "default", + "reference": "0000000000", + "primary": true, + "currencies": [ + { + "balance": 10000, + "available_balance": 10000, + "currency": { + "code": "XBT", + "description": "bitcoin", + "symbol": "฿", + "unit": "bitcoin", + "divisibility": 8 + }, + "limits": [], + "fees": [], + "settings": { + "allow_transactions": true, + "allow_debit_transactions": true, + "allow_credit_transactions": true + }, + "active": true + } + ], + "created": 1464858068745, + "updated": 1464858068745 + } +] + +``` \ No newline at end of file diff --git a/content/checkout/integration-guide/_index.md b/content/checkout/integration-guide/_index.md new file mode 100644 index 0000000..c990f3f --- /dev/null +++ b/content/checkout/integration-guide/_index.md @@ -0,0 +1,6 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Integration guide +description: How to integrate Plue into your existing checkout flow. +weight: 1 +--- diff --git a/content/checkout/integration-guide/authentication.md b/content/checkout/integration-guide/authentication.md new file mode 100644 index 0000000..8b80da4 --- /dev/null +++ b/content/checkout/integration-guide/authentication.md @@ -0,0 +1,38 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 1. Authentication +description: Authenticating with Plue +weight: 2 +--- + +The customer arrives on your web page in the browser and selects the _Pay with Plue_ checkout option. The customer is prompted to authenticate their Plue account by providing their email and password. + +### Endpoints +URL | methods +---|--- +`https://api.plue.io/3/auth/login/` | `POST` + +### Javascript example code: +``` +plue.auth.login({ + user: "joe@example.com", + company: "plue_prod", + password: "joe1234" +}).then(function(user){ + ... +},function(err){ + ... +}) +``` + + + + The API will return a success response with the user details and the javascript SDK will handle the storing of the authentication token for use on subsequent requests. + + + + + + + + diff --git a/content/checkout/integration-guide/balance.md b/content/checkout/integration-guide/balance.md new file mode 100644 index 0000000..e701dd0 --- /dev/null +++ b/content/checkout/integration-guide/balance.md @@ -0,0 +1,78 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 2. Balance check +description: Balance check / currency selection +weight: 3 +--- +The customer's account balance is pulled. You can decide if you want to allow the customer to change their preferred account or currency to make a payment. The customer can see their available balance for the selected accounts as well as the currency conversion rate that matches the currency specified in the order. The customer can change the amount they would need to pay in the currency specified in the order and validate the underlying currency amount that will be charged to their account. The customer can see the fee amount that will be charged to their Plue account before completing the purchase. The customer clicks Confirm to proceed. + +### Endpoints +URL | methods +---|--- +`https://api.plue.io/3/accounts/` | `GET` + +### Javascript example code: +``` +plue.accounts.get({filters: filters}).then(function(res){ + ... +},function(err){ + ... +}) +``` + +The `filters` parameter can be used to customize the response. To retrieve all the user's accounts and currencies, leave out the `{filters: filters}` parameter above. + +To retrieve only the user's primary account, set: +``` +filters = {"primary": true} +``` + +To retrieve only a specific currency whithin the user's primary account, set: +``` +filters = {"primary": true, "currency": "XBT"} +``` + + +Example response: + +``` +[ + { + "name": "default", + "reference": "0000000000", + "primary": true, + "currencies": [ + { + "balance": 10000, + "available_balance": 10000, + "currency": { + "code": "XBT", + "description": "bitcoin", + "symbol": "฿", + "unit": "bitcoin", + "divisibility": 8 + }, + "limits": [], + "fees": [], + "settings": { + "allow_transactions": true, + "allow_debit_transactions": true, + "allow_credit_transactions": true + }, + "active": true + } + ], + "created": 1464858068745, + "updated": 1464858068745 + } +] +``` + + + + + + + + + diff --git a/content/checkout/integration-guide/overview.md b/content/checkout/integration-guide/overview.md new file mode 100644 index 0000000..7d90eb9 --- /dev/null +++ b/content/checkout/integration-guide/overview.md @@ -0,0 +1,37 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Overview +description: Summary of the checkout flow +weight: 1 +--- + +Accepting payments with Plue Checkout is a three step process, with client side and server side actions. + +From your website running in the customer’s browser, Plue securely collects your customer’s authentication details and returns an authentication token. This, along with any other form data, is then submitted by the browser to the Plue server. +Your application can pull the customer’s account balance and let the customer choose a Plue account to make a payment. The customer can confirm the payment details to proceed. +Your server will receive a webhook that includes the transaction details to validate and fulfil the order. + +Using the Plue server directly ensures that no sensitive authentication data is ever stored on your server. + +Create a simple user interface for your customer to select Plue as a payment method on your web page. The steps below describe a suggested checkout flow: + + +**1. Authentication:** +1.1 The customer arrives on your web page in the browser and selects the Pay with Plue checkout option. +1.2 The customer is prompted to authenticate their Plue account by providing their email and password. + +**2. Balance Check / Currency Selection:** +2.1 The customer's account balance is pulled. +2.2 You can decide if you want to allow the customer to change their preferred account or currency to make a payment. +2.3 The customer can see their available balance for the selected accounts +2.4 The customer clicks Confirm to proceed. + +**3. Direct payment and callback processing** +3.1 The transaction is posted to Plue from your client-side code (the post can also be made from server-side code if preferred). +3.2 Plue will trigger a webhook to your server that includes the transaction details to process the rest of your order. +3.3 It is important that your server-side code cross-references the order_id in the metadata and the transaction status before releasing the order. + + + + + diff --git a/content/checkout/integration-guide/payment.md b/content/checkout/integration-guide/payment.md new file mode 100644 index 0000000..c932250 --- /dev/null +++ b/content/checkout/integration-guide/payment.md @@ -0,0 +1,122 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 3. Payment +description: Payment and callback processing +weight: 4 +--- + +The transaction is posted to Plue from your client-side code (the post can also be made from server-side code if preferred). Plue will trigger a webhook to your server that includes the transaction details to process the rest of your order. It is important that your server-side code cross-references the order_id in the metadata and the transaction status before releasing the order. + +### Endpoints +URL | methods +---|--- +`https://api.plue.io/3/transactions/transfer/` | `POST` + +### Javascript example code: +``` +plue.transactions.createTransfer( +{ + amount: 500, + recipient: "merchant@email-provider.com" +}).then(function(res){ + ... +},function(err){ + ... +``` + +Example response: +``` +{ + "id": "00000000-0000-0000-0000-000000000000", + "tx_type": "debit", + "subtype": null, + "note": "", + "metadata": {}, + "status": "Complete", + "reference": null, + "amount": -500, + "fee": 0, + "total_amount": -500, + "balance": 0, + "account": "0000000000", + "label": "Debit", + "company": "Plue_prod", + "currency": { + "description": "Rand", + "code": "ZAR", + "symbol": "R", + "unit": "rand", + "divisibility": 2 + }, + "source_transaction": null, + "destination_transaction": { + "id": "00000000-0000-0000-0000-000000000000", + "user": { + "id": "00000000-0000-0000-0000-000000000000", + "first_name": "", + "last_name": "", + "email": "merchant@email-provider.com", + "username": "", + "mobile": "", + "profile": null + } + }, + "messages": [], + "fees": [], + "created": 1476691969394, + "updated": 1496135465287 +} +``` + +### Webhook +This will be posted to the server url you configure whenever a payment is made. +``` +{ + "event": "transaction.execute", + "company": "company_id", + "data": { + "id": "00000000-0000-0000-0000-000000000000", + "tx_type": "debit", + "subtype": null, + "note": "", + "metadata": {}, + "status": "Complete", + "reference": null, + "amount": -500, + "fee": 0, + "total_amount": -500, + "balance": 0, + "account": "0000000000", + "label": "Debit", + "company": "plue_prod", + "currency": { + "description": "Rand", + "code": "ZAR", + "symbol": "R", + "unit": "rand", + "divisibility": 2 + }, + "source_transaction": null, + "destination_transaction": { + "id": "00000000-0000-0000-0000-000000000000", + "user": { + "id": "00000000-0000-0000-0000-000000000000", + "first_name": "", + "last_name": "", + "email": "merchant@email-provider.com", + "username": "", + "mobile": "", + "profile": null + } + }, + "messages": [], + "fees": [], + "created": 1476691969394, + "updated": 1496135465287 + } +} +``` + + + + diff --git a/content/checkout/usage/_index.md b/content/checkout/usage/_index.md new file mode 100644 index 0000000..460c83f --- /dev/null +++ b/content/checkout/usage/_index.md @@ -0,0 +1,6 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Usage +description: Platform usage. +weight: 4 +--- diff --git a/content/checkout/usage/authorization.md b/content/checkout/usage/authorization.md new file mode 100644 index 0000000..594a188 --- /dev/null +++ b/content/checkout/usage/authorization.md @@ -0,0 +1,22 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Authorization +description: Authorization. +weight: 1 +--- + +The API uses a token-based HTTP Authentication scheme. + +Once a user has logged in and received a token, each subsequent request should include the token in the HTTP Authorization header. Tokens expire 10 hours after creation. Once a token has expired, login is required in order to re-authenticate. + +### Authorization Header + +When making requests, the API key should be included as a token in the `Authorization` header: + +```json +Authorization: Token {token} +``` + + diff --git a/content/checkout/usage/errors.md b/content/checkout/usage/errors.md new file mode 100644 index 0000000..2d60d59 --- /dev/null +++ b/content/checkout/usage/errors.md @@ -0,0 +1,41 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Errors +description: Errors. +weight: 2 +--- + + +When an error occurs in the platform it returns a HTTP response containing two things: + +1. body (formatted in JSON) containing a `message` and `status` +2. and HTTP response code + +The JSON error response always includes a `message` string. If an error occurred as a result of a specific attribute or +key the error details will be outputted in the `data` object. + +Errors will be formatted in one of two ways. A minimal error message: + +```json +{ + "status": "error", + "message": "Error message." +} +``` + +or a descriptive error message including an additional `data` object with details: + +```json + { + "status": "error", + "message": "First error message, Second error message", + "data": { + "field_name1": [ + "First error message." + ], + "field_name2": [ + "Second error message." + ] + } +} +``` diff --git a/content/checkout/usage/events.md b/content/checkout/usage/events.md new file mode 100644 index 0000000..412a16d --- /dev/null +++ b/content/checkout/usage/events.md @@ -0,0 +1,42 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Events +description: Events. +weight: 6 +--- + +The platform has a collection of internal events that can be configured to trigger webhooks. + +Webhooks should always be created with a secure `secret` key. The secret key can be used to identify valid requests to your server. The secret is sent in the Authorization header of the webhook request. + +The platform expects a `200 OK` HTTP response when webhooks are called. If a 200 response is not returned, the platform will retry the webhook up to 12 times with a gradually increasing delay between each retry. + +Every webhook includes a body containing a JSON object. + +```json +{ + "id": 1, + "event": "event.name", + "company": "plue_prod", + "data": { + + } +} +``` + +The attributes in the above object are described below: + +Attribute | Description +--- | --- +id | The unique id of the request. This id is shared between retries of the same request. +event | The event that triggered the webhook +company | The company identifier +data | an object contained different data depending on the event + +### Supported events + +The following webhook events are supported: + +Event | Description +--- | --- +`transaction.execute` | transaction executed (complete/failed) event \ No newline at end of file diff --git a/content/checkout/usage/filters.md b/content/checkout/usage/filters.md new file mode 100644 index 0000000..04720af --- /dev/null +++ b/content/checkout/usage/filters.md @@ -0,0 +1,33 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Filters +description: Filters. +weight: 4 +--- + +The API provides a way to filter and/or sort on listing pages. All filtering and sorting is done via query parameters in the GET request. + +To filter by a field, include it in the URL as a standard query parameter with a `?` delimiting the URL and the start of the query parameters and a `&` between each filtered field. This can be seen below: + +```shell +curl https://api.plue.io/3/admin/transactions/?status=complete&tx_type=debit&orderby=created + -X GET + -H "Authorization: Token {token}" + -H "Content-Type: application/json" +``` + +To sort results, an endpoint will often also include an optional `orderby` query parameter. + +### Complex Filter Fields + +There are several filter field types in the API that offer more complex interactions: + +#### Date Fields + +Date fields can be further narrowed down by filtering on ranges using the greater +than (`__gt`) and less than (`__lt`) suffixes (eg. `created__gt`). + +#### Metadata Fields + +Custom metadata fields can be filtered on their first level children by adding the child attribute as a suffix (`__child_attribute`). So if metadata contains a JSON object with an attribute `name` it can +be filtered using `?metadata__name=joshua`. diff --git a/content/checkout/usage/idempotency.md b/content/checkout/usage/idempotency.md new file mode 100644 index 0000000..82a63ae --- /dev/null +++ b/content/checkout/usage/idempotency.md @@ -0,0 +1,24 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Idempotency +description: Idempotency. +weight: 5 +--- + +The API supports idempotent requests for ensuring the same operations never occur twice. + +To perform an idempotent request, attach a unique key to any `POST`, `PUT` or `PATCH` request made to the API: via the `Idempotency-Key: {key}` header: + +```shell +curl {url} + -X GET + -H "Idempotency-Key: {key}" + -H "Authorization: Token {token}" + -H "Content-Type: application/json" +``` + +API requests made with a new key will get saved along with their HTTP response. Follow up requests made with the same key will always return the same response (As long as the request has the same HTTP method and URL path). The keys (and their associated saved responses) expire after 24 hours. + + diff --git a/content/checkout/usage/pagination.md b/content/checkout/usage/pagination.md new file mode 100644 index 0000000..3210c5b --- /dev/null +++ b/content/checkout/usage/pagination.md @@ -0,0 +1,22 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Pagination +description: Pagination. +weight: 3 +--- + +On listing pages, the API provides a way to paginate results. The default pagination method offered by the API is offset pagination, which allows navigation to an arbitrary point in a list of results as well as via `next` and `prev`attributes. The JSON format returned on paginated listing pages looks like this: + +```shell + { + "status": "success", + "data": { + "count": 1, + "next": null, + "previous": null, + "results": [] + } +} +``` + +The default page size is 15 but can be changed by adding a `page_size` query parameter to the request URL. diff --git a/static/images/favicon.png b/static/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..524650dbbc592098cd55589cf89a9581043bd333 GIT binary patch literal 4905 zcmaJ_dpuMB|KHVyw2@2hL%BpQxt7c35^`%UA>>-0E`;2#Gq;d?L?|Yy>EfEZm`W67 zZXvN%bE)JW#>{W?{r~rPoNdqZe7~Nr*X#LypZD2$oHVSB84s5T7XSd@IcIKS$ND9) zKX4A#x7{~C7y!Vxa?ZriA>!-bhq3t%v$4JC!GT3Z#oCTOUAVNgsMPNv2dk>nk58Y= zyrbFs>V2U|aPecuDU;Q0zKXiuywstiF(*G=_g2#+YJT~8V@xd5&hmIFS0@V2-LD*= zxCm<3ZBP#m*pK)x&@C){DfYjmZ-w;O&%EJYo1fPQaGhI`ty=~NcmnGGKa%)n!+}ZE zI+|I{T-OVjEI=Lqi*(sji41>-=O^|$BMn62&!3Asq$;T+ z>I@%%z6Z;YhY@GF7K~D;2$CX6gaEEh5aHm&+_Oh99jI!KFY6jxXRz0>lu6O{URmpq(H$M9kq-C+bUGyaxbL z-pjKs&JqgP27W1nD?zIvrWaa{3a*F*a@UHK!TR~|C(1EQI_VNgNEnCxqp2G&3Cadt z?=nIGi6AZ-nmYpEObssz5`*9led9j12akuKe(?9jX|*luk1wC%At1yPu3(-GORY3; z^6UMFXCRK~(Sag(QG6Hh2lPrcd>CYsZ%9KAEuRwbLa$uf&`iAZ>F_y#v^jisa9t{p zcSXxV7BURIb5yE8((`asRLJGZ87v4XWuzQeS_ATs#7Yk408Eln`w&=|TXH9OEch6J z7iF|IUxZ-v;M*b-ASjv%7Dvug7XsUN;AA*4scA$;pzG z17c-L$~lpP9uy`isZcN=wy7b>B?CUlJ6Ooskcsk zj*VcIfH>4K2!%eYi&dJO7*bUb-LN11{&}J$0F=>(SeS>JMu!G+Vlce)Y;5}BcsX+b zD79~2!8@YmaykU%naVKBg`RR3cLO0&CQQR~;MWHjX~LBHbylVA4<{cUfLcTJ12@3y zr6}NvaBi3U)X**ut1`*V1ZU<4xyu$%k4SgP43k_|{L}b3@rYDL)+A@guUS!Zz=@2$ z}VS?_YqJ;wKvP+7=O1pmdj7z$2&IGj>%x zryfJ))mi7_q|AlsS;gBBLIx{X4B!uPPx|OzdJ-tlYE*5Sgdp!ionl7(I5EOVdgd<< ze-1~$#Ys7xBvv$ScHayoquY~$%%$AN^da~FJ|;LHkPO-!kiiP(%x9p0fth^)R#X~{ z6R*e~Q(%pW$*hSUai$xBsBpHfAHj!z#L5P7$K?PHrL)52S>dD{7L{bmrtYvPBAc>h zQ#LFrhKnV{eq;${*pwrS0!YVkCb_UcDq}9m9Yv+@y!9S z!4c~ZfE|wb=m0q4h<6Ww3yzq;2Kh=|p<5prg^d_}Y@&O{C)0q~e3O7=lf|!=u~nBJ zgHdauKV6uhNniXqlAEW*j(QnL1DuHgy#`xJl9S!}w~VR!)L6npuG`Y}K-PrZIv!`k zII1eX4O%%))p)g$sXU{dHpB0uAC>#95dU(aHbU^WIR}QO{l1QIdi5vi1F45ZCn;?R zcRDC-Y!dgAXB7R!b2gFvYYV-Sal+uko_bCaRXVwqH2O9Li3T z$>1TKCE0~YcG(@i30;Cp01q2Qww=x8WQnb8>D-@p?1y~m9(UTAv8@ZRQVk{f5RqP~F{4+vlaVi3+emC2;#JNX%`vZC}sldW#_pYU?-36L9)9%4=k9tvPB z?zg@!cPo2mZT@1?j897^;cyoG0z2O$rMObdcy5l-O8N4Go;CXrs-PCZ*q3kA%HeDi zjeTYF4k4D*76Et+Tk*^qM{X!C1gSq{VhHTY_L;1E4EFOA0PFgf-XD69h70p@1|0$9QjX@v1f zio3o6)b-lFC#}bGP}k!OjQod#$MSSRy#zmNW2}9sxm^sY`zLX7=s(4%^-QnTV{Dy2 z4XwC!=46*$)bJojz2N0jDqXRsmwlPE$p5C{WX`-huI|IliYMdXmZrgX~8p_vpZV?&SUPgGjfyJHz?`9Eq`?f z;Rs?@E<@3U0)Kbs)jE-~tZUefIqz6e-F9SmaYXQ0=yDC#mvZwvsrzFp8djCS!NM7dh2+MZAys zw>bx!82(~(M)VNfu+V22H|qN*@e7}y;j-A|uT7YBJ0_3Z9;CF=J}1>ZWYFPR1%f%^>t0h>< zy8HvZ_EH{KfA8Qa@9Dp*?F+^P{#VOqUq*XSZhV(a!Mn!Gb^GP%_4?owst5U~T7;QF zwsZ}>t@C?6+c0*z=f=+hNpdJr3vl(z4>28LFX(5lZGS=59M#4( zujLPA%g})nV`+OYk2j1KH2v9bX;gvvFAiArHKu9&RE*J^S5#5e=3$J zf3%j^An18#z7mc&-e1=HwL{&nxBCU#oDPkT$&-8lC48-67I@$Q z{dUfddUhxAAiw@ksEPGRrngS6E^U0l@{K4Rm|q_cFj%_~)bqfxN_w5q6Uc}6_pq2l z&wM~&o$?H;X3XgU6;5~41;##(`=6Jx0oC?457Sec*T9=sv(EEoFJ}*E0xl`Oj&Ssz zfboE3SRG?Tk>wwLKZ;OBV-^RX*KhEh9j`%%|I>_GebL>k6@ORqHYcWA1t&T-!t*SH zG49UQ@Hx5oUCKKdjb2Z%b!MA@PBG~N;qjW!U+Ie3hEh3vDpd!k( z$Qb@zCY!^WKS0c(7hCNF3Hyt5V04VShUB_bW20_GkcwEEPKLOCprCv$JIZ-sS}P-9 z1+F7dD2YGv#K$A(v%kpiFTCj_%tVuyiA;w0#faeN%PjjxwE)ml3`Fhp@|!3;nzhdw z-gO3>-F|Xg$oyS}+6Psy40kzm1Rkt5=yB+&OzlllI!>r*U|SB2Z2!)+Xg}wj9l+EN zZFJpZs#?hM_Li!t#qprX)1^iaI7lGJ@1B3?In?J2v-{|h4V8c?8~eBF*}o~ zwu?^h;8Rqc6V6~DrcAxfbLw^ej5%Em&1$YIik?$Z^Y@GL5an-N*pZ!C$C(E#$a78C zH-R|f0MT!pN9_mwylJV?=I`=wg}ss8@m0MN-e2EM9UTjiv`DtVskV=I3F!At&WC>& z=etG+dhf?5ZjKjtN@~-`Gp=o0U-Qq=ee%6lKlaDX%{TO|p+c+P&bTzn@u1A-0RFyp zy+GEZLOApeGJ?MTuC#-Dtm$dt>Zj%r>{c6PR>4AV#&W%H>TiuwhsVpw`&pO%g?3q9 zPWmH=lFLml`0bvsOR~B~8}un_h8tX)et$og^0ayr+|{ps%%YO`yfyFFk-}a_=GC~x zImJEYTs6~X>AA}mAhc;Vryb7eG604zf#)&+bzSX8chB1-7nbg#i?dsczZPdRlt*mk z?@9A^rSS5gulzJq_%{{JP`153rZAfltZpnrZh!9v)1Y6H@)UAm-ot1qtqFPWjlCp# z?7^AaAA3S1-EHEcN-0-Bm@4-lb!Ed7wHa1TX0PeKU6u|}_bl`=-R~m{3Cnx;mwaMp zK>ip?lUK4WQ}2srKeoRn<*ZYwMfjlp##14$DQ0HYy|2d7OvLCIGr>x>a%Lx!B551> z>_S!|&4_?U8>M)v?GzhUE-lmwmGWl7R%NKLeze$(!Myg-bn>%2)KVeqY(V9PxM$dDiVw1$RI<>$J%S0~eVIi9zt)bw|+;<803U-lk%+PlHY>DI)8pSE4m6U*5Z9T$|gfZQ&L zNAUglbo|AZiMwOKJrYLo!CC>F`MS>Aj-<+82|h5W^~e z@86L>>R{K2(c=A|iH+Gid%O_|SFg^yA-zerNQLpi@gwAuNgq^BCJM&#?D*~L1}Qq4 zTx7&g#D!^Qh`yY7*U+1Z^rd-n50YH29qVN+rQ002B?B{}Wa_55}0W1_##|Co^eye>$d+KTT1 zwUg9`000f4vYf2$SEN%jBRA?ruP&5v3qF(}fD(ZDm%M3lL<-z6mBn$Zw1lxFDalz` zS5JGFfJLTaRPiY*56&iIREbEAzxxfA6-=t@B&Fo`6H@0Eehkdjr<)lM^+}7(KFZKYK`H2XpQzx;99K>$hW6}b$K|xG))zT}|FHhCBQK#%Mb*j_ zG@AJaY)vSI`R@Lob!4OD1al)L62rNp8Z`mJusfweXUj>vgd8a*M0UGajcDTsEMXC4 z2-&Y#!B)IVanDhzJl!304M&i2uUQG}HSZ=jsJxtzcE##Uzuy#fbNa}Mj63E{loTWl zGKo2eTT#qoEJ&T3 zIlCWn*!n#v8emIa+pvM66Z$bpDUr;H`BMuHp=>@i(vM!NN?^mu$Hd_Tvd1UfXirYg zXMq%7izX5K&2pd^5qvIlR;`N`-S2lThZD_F4h zIU@RyK2i>`yZAv2QGvZy_dBU}P$N}vx)dLjMPD3QZB{oFO9MxqKEB3^8$uYw@QA$p z_jH^?boK)o_dGy9iOf|MtB)@nAd-fv(}P*iG81e=1G!A?U(uEWVqzm1x`~9%8q0%W zG?%F{hWTn*{#s{q0OWeOGu3~uW{Q20Y0z$&Fk!vRlM^0PGY$jG0PPIdrgNcos{Ze<^`r$RXN~vFyNn^h`9f>A%gMH!j$OP>)Hsi=Y_gy zM&74xoYcll z&Ib1Q1#6g*e{@B{njyYD&p-92N$IzJ$4~e}{ryZ(@6UmV*ul-H9s#qG zvI7Nn)+r2!z^A_yl++m|-!+Fm2qt^`X@aC~mumj>MEW$vMHWMjr(f_M%ncP1$okQO z<^M1RnH~~o63k7l)8=PL)+u!3JE#lKwZ)$lJpOaF_4J?-t-oM10TKPcgLy^m4W*^7 zk!&9wBlkR8MFdMLUoWc@z|NBtHn&C``Rh2a)kP+9VLt{f zD0aPU(LW<{aPSBhYXE~oGIuu)FT|*4UYd&k1lxLXS0lGWzSe_JPT0q^&nm2o=N>HF%|@BB zRq7RpE{WeT$&y<2O8oRG3vUSWkn0PKI+65>g z$X32odp)=`Cy=oUdb5#X(FNZwi{B7|66#sgRe}#;>-hxGUEFP>pUritko5tZ^l?X! z4lvewP6}|2^}4U?yP(!B|YB+|mXn9IbJyVP-dG&_9K}=rqU@~qoT>KkKJ0!(VomO6D4##h`GwG`;mi19^ z1siJ99alfCMO@bM2>#ChhhM@@e;lb#Oa@))fS?F_9$A>8a^+UO+08T_(4{6FtCj6NBclG`%VV71-F&!DKS;pkRkuxoU} zmf{?Jg^h6U?lSH7^;oibC{YzGcb1XArw!DUn`it;<+EDVh^!)97vmG+YCOKveK)wQ z^$B{+;l<^&b}s4eS3TItBTar=Iew|90;V|sIk9?YHzMwp0k(~$vQ3ihV)5VZom}G4 zDDz#dN`+-3v(JhlWA?sF`ZcAIEgIH7tSoca5+Lyq>k?})Jqx-sec-D9%fV7t(OH8Q zR$55KFtSNTUFDoKDD@Qnd<`#Hivsdp@zd9hTHuwyq5Y485;STyG46V76xDi;_NG8G zoasp5Py$;-__K;!MO(%q2eAVHX?*8}4OFK4zaZjlzqSxe< zWDfpH0=*3!i0Q@F*@p1jOl@kW(O?o;J)A}^CSGr&kRthFY1DTM8#%PIxz?N9!hN(o z9d()!$7s6`my8k;b@>(VQxXl-_HKmPl5oM&1-vzN+7)y#Cmbn=n?XsPRUl82ZBs&9 zcK}}O<5`(O4l_!~TN{aQJ~C4NhS@sv#yU1K27C2M4uy^rX7{ixYl|e$qh6Y<&~|8+ z)9%}9TRmPA8{4Kz?3#T0OC&X$6B_IH-U&E6ADlVq{NVbxn)jwCNI*k*kzxTvRGnk& zLiY=)+OFnQoLIlG{En4Z#N)r)nWk;M+O?p?I>SL$5^QH<8@LxIyz}7_cG1sP?XH+E2uDPG_%yJ~>Tbe7oJHq%C+3J5E!_(oHi zNu;L$-uk@jEh;>+`2uRyW#c(-PuL7p$H7S%-z^_Tft5I?rY0+MTFrOZ%3lUU8Ri4@ zp@E7tkkBqt5L8_mz2Xw<@5M5QN_>pAhlrwjH0-Xm%2tfWvV%oE^xxZw+w1B6oJac# z&kq9BeD2}Kt@t=zP(a~YQ+>xq1VN1oUPl2ms zkSz5WAN52(arkA2qH7V!x!bwQ*a5jqz>PX`@bQ}fs<$O`Urr+x9V|cjtjV<9V60`J zdbNa^``W;1$VJPN!w8&i*n+Aje~vDJ*x_prm1$NtqR=GVzms@cQzN$=4NFU$_o~ad zvDC0U#L7-$`Nl~9+Au1<3CXxZs2Q5y8NoK=2%urK6iB9wPO#P@0b=(&#J+(&fBxMs ze=M|*`181@tfH>AJZFfPBJ}NVDt1{6j8?T8$?)WbLx^Xv9o=a32XhEQ?x8ifuKc`3 zlqTLoE8@4{+O5QfX8}JqtuCYwrina>f>sya60CPXbN9ZP)>-qK!t=32prlT#R5qJhMtV|DgCC$Y z!h{cyyVgavuYvYUwle^eWxdYJID8?rUW7UY%CxH_a#IH?cNjsIb zcxHE1NO_j0TcQ?S;rQxc=UcfyScTfk98A1#1XM*xA(Mjr;DU<<`r6luh3%SXT|X*5 zkS?Z--s2lWM3=)VAzWX&$K84r_itlKvAHv^oP|_ugilInB=X@S^o?FaB5u9_qOgIF zHUb+`;I6(pvRU!L@AJ0&3YlHSzInG|q+m!kNiUcApM-w3+^8WL=7$R$*2`15NALMN zd4F>z?)r$d_i`*rwt|1LNykibb&>Z;2HWc_0!>2{kd==8GTWA~`}L9dl91M3!L?X^?)qQH=j~d@=&32YBW#wp#LpCv`hiv&Z6uluU(%JV%lOR5Ew1nwqx+M41I2Vqve zn~W}x$312JhC3tY?M_y15eINK8_nADsnyyXAyTiJs`fxGe^b>aS#Mi^|M)kM`j@L@ z^BHOp3*mQ}>D3sJz}2iITrHm5vD23q0uFZSuQb7;?e?n>rhbZ zx9|PAEb#*Y>RC%|6)=itviP&13@2?x3anhKDwKBvvd}vD8U3Ia9dpmUz+Gqes^JRf z&-1yAMOuK^LU7ZMiTuF*#goqq?eVmcutBfRA4lCa*|5qD4W9bgZ|`>|;ZB-OLI~WR zo>0%qzi*f;3J4v4x-FmAEcmQJ0&k~WkIS}-Fg_KyBQbv$)J3-!n=&=Wsr}Eu0cWTy zP0@DIde`48?iSD~yeH zh*2NZvqO`~@G5q==an!rCl7@)2oZ+4)>;+P+-Xnoid@g@w;dIuah%8eji0 zi{6vpY4r@<$M#O2G!dyVW5)yUX6g4{jD+2TK659s_un5dHuHD{7}+k13qK8S84{=6 z0Bw>EhK{hR<*y32nm9la(T!&(PD9~D6)D!6x4)u64;4$PmwxvTwa4e4NjC-V;qkOl z!tO{GAkh3+(dq(*^K;Lv0yurrNOe}iuT$X5Q0>KS+UuQ5j^yXEnyt>N;`sS2TqQr$ ztu@60#dlFHQWU?=2Z|mC&LryBxtmQlCz7E}8@ZDKdh&*7yJL;#wqgWUnL`{CbppnQ zL18mXKL0VMudZMd$Xoq7*+Rj0FUr<3FE}FAv~Ey);yP*c{EEHgkKt7M82hvNFzb-fE*=BUF9p)hi;1N2^(2;)4rQt1E- zw$npiaVJN!^IJdoj`VMa_^Kq_r}g|kubnBnqP|uObD?_~38fE#FEvZd6uLoP^Bgfg zUQzmp!tD!*6~-E8CaM3}91h1m3%xY7Xx^M=5AlJ8yRl}nB*}Yc-66Hl zYa0=RH~EnjlPRM%f|66-1mfy~{SdTU4ySM1mm#pt5Oth6^(mg&XxE&QjXVmYBHQ^M zmBym|OBB$-j9;tgx4^Hwb*X~;6}NOfirjgg<5#|!856M?GSVtV8~(YeqUBfZ28xr} zuD&Zoab-q!kP~Rgh>E z!v|ts=C(ug9?fOqo|00ByycH-f06xa*>VF@OY^?r&XZo!1428yl9{skQfJv;f44OM zG1j4UTayLm*p5w+9h~ecKjhu=%x=2v2Kn3n1^KuZD;myy-VKURIqKIO6dmd4&XM^R zDgh3F5{ZMqb|tylnI5gk?F2$%Z0Q0LQl%1gp*-=&9kI)(UX=ttP0-p1;qn!%;&@(f z?HK%|5;PjI_$4#Sj3(c6@>v?EH|Lxr9v@C>i4;4qPVM;9uzEmL@@Vt_42=De3=`cG zAf4kdK3Z17>GYZI%cY^dq@7GjuS2E`AXE?s;ZFYy8X-q8dSd()g@4ig-5EwQ^#%2( z*liK0XwlT0fA-7;%z>HZOohuQzlsJ&3j6 zQiAeMl)aB~MGhTmzSmZ{fO-rQFJL=^w1i3|V}V_pwh4G(b>8S;OomCJ43?{P-i~x5 zlzk_Ptn_%SmPHY0!3>$P7#3-C$l+ScQOl*nN7iEesXtn-$Mk6=`a2g`qVkPC!hamt ztHMhWV&KQ03FD?l;+d>U=O0WsvYNL2iQvnG*(Er6;=&sxH<-)dM2$3}E zs&~ECY|yrs!DO<~&@0aT0WO$V+9%n3M&vG7DXc<+(>1t;o)R5j;R0hKs zY@Uu?6vV;2$e6!c9I}sV%Ajz0G`^S97U!64G;rJvQ_#I>7Br{@EuE7Ar7`$z65D801ic zRWO~caB3zB%{aK`fBErfo6#_S)6^6I;SM%+U%#kvz0?7d=MmC92bwtoE~iWv*1 zu_>kyfGu;O7?A(I7sCj`dOx=Sxw8Go$S(`${uNp!YyuyNjtc4h1S#ZL zM=@mni)o=qbSGKJ7jIHk@+#kw{TS&Wid^g26*R`ApL513#bE*lZI#(r$%6p`omv7# z6Q(E|n#m)=P~fneHxQZ6d2FOcm#k;sN)ZfbYS;C!=H__}Rjw7JKvF}=XeTsWN*_pq z0Z21_-WsI1yDdq*?SK3&5vSe$sY`1h6~?1wrO>IgbQ3A&4P5*;p0A)4F9ku$O`nPV z!f?|wfPO-?tQ*&f38}jUpni$ji?DsOz0NXTBQp-CU1(j7utpP(YEEdw{q8rV!(wC;UwH(;fmD5JLQI$zC^1pfahG0WGZ)ZCM4k|U8R}%Rv#auh z*~I!iKF;DEznj=7As=hKYHy7u-m{VQ&r5fo?#4ZSvTX6t%hkbUL&z%&o61^0W6+qy>LuB=UQaH#k3*Cg z^$$buU}D58+FObUN?07!PZq#Ij(LT8KZE~&gL+Rg54*7rS}r{7ucQ>9EUzI~``+UF F{{d{|Hc|ip literal 0 HcmV?d00001 diff --git a/static/images/logo.png b/static/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d60d18b5c7160defbe06a41c4c0cf5911f68c512 GIT binary patch literal 63847 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 lmG!5G|1UTfqVfAKM{V=5!o#NYJ~j- Date: Mon, 8 Jul 2019 20:09:11 +0200 Subject: [PATCH 02/19] Added submodule --- themes/hexon-hugo-theme | 1 + 1 file changed, 1 insertion(+) create mode 160000 themes/hexon-hugo-theme diff --git a/themes/hexon-hugo-theme b/themes/hexon-hugo-theme new file mode 160000 index 0000000..a0d10f6 --- /dev/null +++ b/themes/hexon-hugo-theme @@ -0,0 +1 @@ +Subproject commit a0d10f6dab235eac34c2048e81542f41f3eb4613 From 7082b6f47a0362aa89e3d74e4d87b1e27a7cdda2 Mon Sep 17 00:00:00 2001 From: OdinsPlasmaRifle Date: Mon, 8 Jul 2019 20:13:31 +0200 Subject: [PATCH 03/19] Added etc config --- etc/compose/__init__.py | 0 etc/compose/docker-compose.yml | 14 ++++++++++++ etc/compose/docker-services.yml | 12 ++++++++++ etc/docker/Dockerfile | 7 ++++++ etc/docker/build.Dockerfile | 18 +++++++++++++++ etc/docker/cloudbuild-no-cache.yaml | 24 ++++++++++++++++++++ etc/docker/cloudbuild.yaml | 32 +++++++++++++++++++++++++++ etc/docker/docker-entrypoint.sh | 3 +++ etc/helm/production/values.yaml | 34 +++++++++++++++++++++++++++++ etc/nginx/conf.d/default.conf | 14 ++++++++++++ 10 files changed, 158 insertions(+) create mode 100644 etc/compose/__init__.py create mode 100644 etc/compose/docker-compose.yml create mode 100644 etc/compose/docker-services.yml create mode 100644 etc/docker/Dockerfile create mode 100644 etc/docker/build.Dockerfile create mode 100644 etc/docker/cloudbuild-no-cache.yaml create mode 100644 etc/docker/cloudbuild.yaml create mode 100644 etc/docker/docker-entrypoint.sh create mode 100644 etc/helm/production/values.yaml create mode 100644 etc/nginx/conf.d/default.conf diff --git a/etc/compose/__init__.py b/etc/compose/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/etc/compose/docker-compose.yml b/etc/compose/docker-compose.yml new file mode 100644 index 0000000..7343193 --- /dev/null +++ b/etc/compose/docker-compose.yml @@ -0,0 +1,14 @@ +version: "2.1" + +services: + webapp: + extends: + service: webapp + file: ./docker-services.yml + ports: + - ${LOCAL_PORT}:80 + networks: + - main + +networks: + main: diff --git a/etc/compose/docker-services.yml b/etc/compose/docker-services.yml new file mode 100644 index 0000000..63c792a --- /dev/null +++ b/etc/compose/docker-services.yml @@ -0,0 +1,12 @@ +version: "2.1" + +services: + webapp: + image: ${IMAGE_NAME}:${VERSION} + env_file: $PWD/.env + logging: + driver: "json-file" + options: + max-size: "50m" + max-file: "10" + restart: always diff --git a/etc/docker/Dockerfile b/etc/docker/Dockerfile new file mode 100644 index 0000000..451eddd --- /dev/null +++ b/etc/docker/Dockerfile @@ -0,0 +1,7 @@ +FROM nginx:latest +COPY etc/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +COPY etc/nginx/conf.d/ /etc/nginx/conf.d/ +COPY public/ /usr/share/nginx/html/ +ENTRYPOINT ["docker-entrypoint.sh"] +RUN chmod +x /usr/local/bin/docker-entrypoint.sh +CMD ["nginx", "-g", "daemon off;"] diff --git a/etc/docker/build.Dockerfile b/etc/docker/build.Dockerfile new file mode 100644 index 0000000..042afad --- /dev/null +++ b/etc/docker/build.Dockerfile @@ -0,0 +1,18 @@ +FROM alpine:3.8@sha256:ea47a59a33f41270c02c8c7764e581787cf5b734ab10d27e876e62369a864459 +ENV HUGO_VERSION=0.55.6 +ENV HUGO_TYPE=_extended +ENV HUGO_ID=hugo${HUGO_TYPE}_${HUGO_VERSION} +ADD https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_ID}_Linux-64bit.tar.gz /tmp +RUN tar -xf /tmp/${HUGO_ID}_Linux-64bit.tar.gz -C /tmp \ + && mkdir -p /usr/local/sbin \ + && mv /tmp/hugo /usr/local/sbin/hugo \ + && rm -rf /tmp/${HUGO_ID}_linux_amd64 \ + && rm -rf /tmp/${HUGO_ID}_Linux-64bit.tar.gz \ + && rm -rf /tmp/LICENSE.md \ + && rm -rf /tmp/README.md +RUN apk add --update git libc6-compat libstdc++ \ + && apk upgrade \ + && apk add --no-cache ca-certificates +WORKDIR /app +COPY . /app/ +CMD ["hugo"] diff --git a/etc/docker/cloudbuild-no-cache.yaml b/etc/docker/cloudbuild-no-cache.yaml new file mode 100644 index 0000000..86abb18 --- /dev/null +++ b/etc/docker/cloudbuild-no-cache.yaml @@ -0,0 +1,24 @@ +steps: +- name: 'gcr.io/cloud-builders/docker' + args: [ + 'build', + '-t', '$_IMAGE-build:latest', + '-t', '$_IMAGE-build:$TAG_NAME', + '-f', 'etc/docker/build.Dockerfile', + '.' + ] +- name: 'gcr.io/cloud-builders/docker' + args: [ + 'run', + '-v', '/workspace/public:/app/public:rw', + '$_IMAGE-build' + ] +- name: 'gcr.io/cloud-builders/docker' + args: [ + 'build', + '-t', '$_IMAGE:latest', + '-t', '$_IMAGE:$TAG_NAME', + '-f', 'etc/docker/Dockerfile', + '.' + ] +images: ['$_IMAGE-build', '$_IMAGE'] diff --git a/etc/docker/cloudbuild.yaml b/etc/docker/cloudbuild.yaml new file mode 100644 index 0000000..e620acd --- /dev/null +++ b/etc/docker/cloudbuild.yaml @@ -0,0 +1,32 @@ +steps: +- name: 'gcr.io/cloud-builders/docker' + args: ['pull', '$_IMAGE-build:latest'] +- name: 'gcr.io/cloud-builders/docker' + args: ['pull', '$_IMAGE:latest'] +- name: 'gcr.io/cloud-builders/docker' + args: [ + 'build', + '--cache-from', + '$_IMAGE-build:latest', + '-t', '$_IMAGE-build:latest', + '-t', '$_IMAGE-build:$TAG_NAME', + '-f', 'etc/docker/build.Dockerfile', + '.' + ] +- name: 'gcr.io/cloud-builders/docker' + args: [ + 'run', + '-v', '/workspace/public:/app/public:rw', + '$_IMAGE-build' + ] +- name: 'gcr.io/cloud-builders/docker' + args: [ + 'build', + '--cache-from', + '$_IMAGE:latest', + '-t', '$_IMAGE:latest', + '-t', '$_IMAGE:$TAG_NAME', + '-f', 'etc/docker/Dockerfile', + '.' + ] +images: ['$_IMAGE-build', '$_IMAGE'] diff --git a/etc/docker/docker-entrypoint.sh b/etc/docker/docker-entrypoint.sh new file mode 100644 index 0000000..a1be715 --- /dev/null +++ b/etc/docker/docker-entrypoint.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exec "$@" diff --git a/etc/helm/production/values.yaml b/etc/helm/production/values.yaml new file mode 100644 index 0000000..e7e0b71 --- /dev/null +++ b/etc/helm/production/values.yaml @@ -0,0 +1,34 @@ +# Default values for rehive-service. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +deployment: + replicaCount: 1 +image: + repository: gcr.io/rehive-services/client-plue-docs + tag: latest + pullPolicy: IfNotPresent +service: + name: nginx + type: NodePort + externalPort: 80 + internalPort: 80 +ingress: + enabled: true + hosts: + - docs.plue.io + annotations: + kubernetes.io/ingress.class: "nginx" + kubernetes.io/tls-acme: "true" + tls: + - hosts: + - docs.plue.io + secretName: client-plue-docs-tls +management: + enabled: false +postgres: + enabled: false +redis: + enabled: false +rabbitmq: + enabled: false +workersEnabled: false diff --git a/etc/nginx/conf.d/default.conf b/etc/nginx/conf.d/default.conf new file mode 100644 index 0000000..3ec2e0c --- /dev/null +++ b/etc/nginx/conf.d/default.conf @@ -0,0 +1,14 @@ +server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} From 08e9a7f87063a651742c87336850b80de2333e66 Mon Sep 17 00:00:00 2001 From: OdinsPlasmaRifle Date: Mon, 8 Jul 2019 20:18:23 +0200 Subject: [PATCH 04/19] Added new file --- rdeploy.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 rdeploy.yaml diff --git a/rdeploy.yaml b/rdeploy.yaml new file mode 100644 index 0000000..2f21e7b --- /dev/null +++ b/rdeploy.yaml @@ -0,0 +1,11 @@ +version: '1' +configs: + production: + project_name: client-plue-docs + docker_image: gcr.io/rehive-services/client-plue-docs + cloud_project: rehive-services + cluster: production + namespace: client-plue-docs + helm_chart: rehive/rehive-service + helm_chart_version: 0.1.36 + helm_values_path: ./etc/helm/production/values.yaml From aab804afc6238b79c6610b80af69bb08631474c1 Mon Sep 17 00:00:00 2001 From: OdinsPlasmaRifle Date: Mon, 8 Jul 2019 20:58:08 +0200 Subject: [PATCH 05/19] Added env from secrets option --- etc/helm/production/values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/helm/production/values.yaml b/etc/helm/production/values.yaml index e7e0b71..6a24f14 100644 --- a/etc/helm/production/values.yaml +++ b/etc/helm/production/values.yaml @@ -7,6 +7,8 @@ image: repository: gcr.io/rehive-services/client-plue-docs tag: latest pullPolicy: IfNotPresent +envFromSecret: + enabled: true service: name: nginx type: NodePort From 4dbd44c78cd5a05e3a3cc1a20662265e0c796c7c Mon Sep 17 00:00:00 2001 From: OdinsPlasmaRifle Date: Mon, 8 Jul 2019 21:00:01 +0200 Subject: [PATCH 06/19] Setting env from secret to false --- etc/helm/production/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/helm/production/values.yaml b/etc/helm/production/values.yaml index 6a24f14..e2b56d9 100644 --- a/etc/helm/production/values.yaml +++ b/etc/helm/production/values.yaml @@ -8,7 +8,7 @@ image: tag: latest pullPolicy: IfNotPresent envFromSecret: - enabled: true + enabled: false service: name: nginx type: NodePort From fde1d0ad86f1690a00079072724d3b89e110900d Mon Sep 17 00:00:00 2001 From: Mwangi <8320816+kidynamit@users.noreply.github.com> Date: Wed, 27 May 2020 17:47:48 +0200 Subject: [PATCH 07/19] upgraded production values and the rdeploy values --- etc/helm/production/values.yaml | 5 ++++- rdeploy.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/etc/helm/production/values.yaml b/etc/helm/production/values.yaml index e2b56d9..f0b747a 100644 --- a/etc/helm/production/values.yaml +++ b/etc/helm/production/values.yaml @@ -3,6 +3,8 @@ # Declare variables to be passed into your templates. deployment: replicaCount: 1 + command: null + args: null image: repository: gcr.io/rehive-services/client-plue-docs tag: latest @@ -33,4 +35,5 @@ redis: enabled: false rabbitmq: enabled: false -workersEnabled: false +workers: + enabled: false diff --git a/rdeploy.yaml b/rdeploy.yaml index 2f21e7b..ff96267 100644 --- a/rdeploy.yaml +++ b/rdeploy.yaml @@ -7,5 +7,5 @@ configs: cluster: production namespace: client-plue-docs helm_chart: rehive/rehive-service - helm_chart_version: 0.1.36 + helm_chart_version: 0.2.2 helm_values_path: ./etc/helm/production/values.yaml From 115f092f85e414eb1be69f83940ccb3f09ce58d3 Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Fri, 21 Aug 2020 15:40:01 +0200 Subject: [PATCH 08/19] Shifted to the new payment processing method docs --- content/checkout/_index.md | 3 - content/checkout/core-resources/_index.md | 2 +- content/checkout/core-resources/accounts.md | 72 ---------- content/checkout/core-resources/invoice.md | 64 +++++++++ .../core-resources/payment-processor.md | 28 ++++ content/checkout/core-resources/quotes.md | 41 ++++++ .../checkout/core-resources/transactions.md | 101 +++++--------- content/checkout/core-resources/users.md | 71 ---------- content/checkout/custom-integration/_index.md | 6 + .../custom-integration/closed-loop.md | 41 ++++++ .../checkout/custom-integration/invoicing.md | 87 ++++++++++++ .../checkout/custom-integration/open-loop.md | 108 +++++++++++++++ .../checkout/custom-integration/overview.md | 8 ++ .../custom-integration/payment-quotes.md | 49 +++++++ .../checkout/custom-integration/payments.md | 48 +++++++ .../checkout/custom-integration/webhooks.md | 84 +++++++++++ content/checkout/get-started/introduction.md | 28 +--- content/checkout/get-started/quick-guide.md | 130 +----------------- .../checkout/hosted-payments-page/_index.md | 6 + .../hosted-payments-page/invoicing.md | 87 ++++++++++++ .../checkout/hosted-payments-page/overview.md | 23 ++++ .../checkout/hosted-payments-page/webhooks.md | 84 +++++++++++ content/checkout/integration-guide/_index.md | 6 - .../integration-guide/authentication.md | 38 ----- content/checkout/integration-guide/balance.md | 78 ----------- .../checkout/integration-guide/overview.md | 37 ----- content/checkout/integration-guide/payment.md | 122 ---------------- content/checkout/usage/_index.md | 6 - content/checkout/usage/authorization.md | 22 --- content/checkout/usage/errors.md | 41 ------ content/checkout/usage/events.md | 42 ------ content/checkout/usage/filters.md | 33 ----- content/checkout/usage/idempotency.md | 24 ---- content/checkout/usage/pagination.md | 22 --- 34 files changed, 809 insertions(+), 833 deletions(-) delete mode 100644 content/checkout/core-resources/accounts.md create mode 100644 content/checkout/core-resources/invoice.md create mode 100644 content/checkout/core-resources/payment-processor.md create mode 100644 content/checkout/core-resources/quotes.md delete mode 100644 content/checkout/core-resources/users.md create mode 100644 content/checkout/custom-integration/_index.md create mode 100644 content/checkout/custom-integration/closed-loop.md create mode 100644 content/checkout/custom-integration/invoicing.md create mode 100644 content/checkout/custom-integration/open-loop.md create mode 100644 content/checkout/custom-integration/overview.md create mode 100644 content/checkout/custom-integration/payment-quotes.md create mode 100644 content/checkout/custom-integration/payments.md create mode 100644 content/checkout/custom-integration/webhooks.md create mode 100644 content/checkout/hosted-payments-page/_index.md create mode 100644 content/checkout/hosted-payments-page/invoicing.md create mode 100644 content/checkout/hosted-payments-page/overview.md create mode 100644 content/checkout/hosted-payments-page/webhooks.md delete mode 100644 content/checkout/integration-guide/_index.md delete mode 100644 content/checkout/integration-guide/authentication.md delete mode 100644 content/checkout/integration-guide/balance.md delete mode 100644 content/checkout/integration-guide/overview.md delete mode 100644 content/checkout/integration-guide/payment.md delete mode 100644 content/checkout/usage/_index.md delete mode 100644 content/checkout/usage/authorization.md delete mode 100644 content/checkout/usage/errors.md delete mode 100644 content/checkout/usage/events.md delete mode 100644 content/checkout/usage/filters.md delete mode 100644 content/checkout/usage/idempotency.md delete mode 100644 content/checkout/usage/pagination.md diff --git a/content/checkout/_index.md b/content/checkout/_index.md index 60ebab5..cb0f6ac 100644 --- a/content/checkout/_index.md +++ b/content/checkout/_index.md @@ -4,7 +4,4 @@ title: Merchant checkout description: Merchent checkout API documentation. weight: 1 linkTo: /checkout/get-started/introduction -references: - - title: Javascript SDK - url: https://www.npmjs.com/package/@pluewallet/plue --- diff --git a/content/checkout/core-resources/_index.md b/content/checkout/core-resources/_index.md index cd4cb16..19ff1b0 100644 --- a/content/checkout/core-resources/_index.md +++ b/content/checkout/core-resources/_index.md @@ -2,5 +2,5 @@ date: 2018-09-17T15:21:22+02:00 title: Core resources description: Core resources of the platform. -weight: 3 +weight: 4 --- diff --git a/content/checkout/core-resources/accounts.md b/content/checkout/core-resources/accounts.md deleted file mode 100644 index 88b9fe0..0000000 --- a/content/checkout/core-resources/accounts.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Accounts -description: Account resources. -weight: 2 ---- - -### Object - -This object can be used to check the currency balances for a user before approving a transaction. - -The full account object with a single currency looks like: - -```json -{ - "name": "default", - "label": "Default", - "reference": "0000000000", - "primary": true, - "user": { - "id": "00000000-0000-0000-0000-000000000000", - "username": null, - "email": "joe@example.com", - "mobile": "+27840000000", - "first_name": "Joe", - "last_name": "Soap", - "profile": null - }, - "currencies": [ - { - "balance": 0, - "available_balance": 0, - "currency": { - "code": "USD", - "description": "United States dollar", - "symbol": "$", - "unit": "dollar", - "divisibility": 2 - }, - "limits": [], - "fees": [], - "active": true, - "settings": { - "allow_transactions": true, - "allow_debit_transactions": true, - "allow_credit_transactions": true - }, - "archived": false, - "created": 1538573021547, - "updated": 1538573021547 - } - ], - "archived": false, - "created": 1538573021502, - "updated": 1538573021502 -} -``` - -### Endpoints - -To view an account or its currencies you can use the following endpoints. Keep in mind, accounts are always identified by their `reference`. - -section | type| URL | methods ----|---|---|--- -user | multiple | `https://api.plue.io/3/accounts/` | `GET`, `POST` -user | single | `https://api.plue.io/3/accounts//` | `GET`, `PUT`,`PATCH` -user | multiple | `https://api.plue.io/3/accounts//currencies/` | `GET`, `POST` -user | single | `https://api.plue.io/3/accounts//currencies//` | `GET`, `PUT`,`PATCH` - -### Usage - -Usage remains the same for all endpoints. Simply invoke one of the allowed HTTP methods with the correct `Content-Type` and a `Authorization` header. diff --git a/content/checkout/core-resources/invoice.md b/content/checkout/core-resources/invoice.md new file mode 100644 index 0000000..918ba70 --- /dev/null +++ b/content/checkout/core-resources/invoice.md @@ -0,0 +1,64 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Invoices +description: Invoice resources. +weight: 1 +--- + +The Invoice the core resource that encapsulates all logic around receiving user payments. All other resources are associated with the Invoice in various ways. + +### Statuses +The statuses of an invoice will tell you whether or not the user has paid, underpaid, overpaid etc and is the primary mechanism for triggering third party logic on your end. + +status | description +---|--- +draft | Invoice is created but not finalised for viewing by the end user. +processing | A primary payment processor has been selected but not Completed payment has been made yet. +paid | The end user has successfully made the payment for their quoted amount. +underpaid | The end user has paid less than their quoted amount. +overpaid | The end user has paid more than the quoted amount +expired | The Invoice has passed it’s expiry date. +complete | The invoice has been paid and converted into the requested currency. +failed | An error has occurred to cause the Invoice to permanently fail. +late | The user has paid the full quoted amount but after the due_date of the invoice. +cancelled | The invoice has been set to cancelled by a manager. + +### Object + +``` +{ + "id": "deb62287-dbc6-4f11-8f83-d753f6cf1284", + "user": { + "id": "fbb59810-04ab-401a-a017-d293dfa5c7c5", + "base_currency": null + }, + "request_reference": "123456789", + "request_currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "request_amount": 200, + "primary_payment_processor": PaymentProcessorObject, + "description": null, + "metadata": null, + "status": "overpaid", + "account": null, + "redirect_url": "?request=deb62287-dbc6-4f11-8f83-d753f6cf1284", + "payer_email": "customer@plue.com", + "return_url": null, + "payment_processor_quotes": [ + QuoteObjectArray + ], + "available_payment_processors": [ + PaymentProcessorArray + ], + "expiration_date": null, + "due_date": null, + "created": 1596795265440, + "updated": 1596795408826 +} +``` diff --git a/content/checkout/core-resources/payment-processor.md b/content/checkout/core-resources/payment-processor.md new file mode 100644 index 0000000..5a4e664 --- /dev/null +++ b/content/checkout/core-resources/payment-processor.md @@ -0,0 +1,28 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: PaymentProcessor +description: PaymentProcessor resources. +weight: 2 +--- + +### Object + +Payment processors objects contain information for the relevant payment options available for users. They are identified by the `unique_string_name` field which can be used to PATCH the Invoice’s `primariy_payment_processor` field for selecting/changing payment processors. + +Each payment processor has a unique subtype and identifier field + +### Object + +``` +{ + "id": "b5950a31-f954-44ff-8860-3a18d7349cf5", + "unique_string_name": "native", + "logo": "", + "name": "Native", + "description": "Pay using a wallet balance.", + "currencies": [], + "longest_expiration_time": 0, + "rehive_transaction_identifier": null, + "rehive_subtype": "receive_email" +} +``` diff --git a/content/checkout/core-resources/quotes.md b/content/checkout/core-resources/quotes.md new file mode 100644 index 0000000..f24c85f --- /dev/null +++ b/content/checkout/core-resources/quotes.md @@ -0,0 +1,41 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Quotes +description: Quote resources. +weight: 3 +--- + +The Quote object contains the amount and currency the Payment Processor expects the user to pay to settle the Invoice total. + +### Object + +``` +{ + "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", + "request": 16, + "reference": "459b3407-3009-4f77-bbbf-5d6e12788958", + "deposit_details": {}, + "payment_processor": { + "id": "19dff821-a349-4bbc-a929-72bf9fcef4d1", + "unique_string_name": "native_otp", + "logo": "", + "name": "Native OTP", + "description": "Pay using a wallet balance via an OTP.", + "currencies": [], + "longest_expiration_time": 0, + }, + "currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "amount": 200, + "total_paid": 400, + "expiration_date": null, + "status": "overpaid", + "conversion_quote": null +} +``` diff --git a/content/checkout/core-resources/transactions.md b/content/checkout/core-resources/transactions.md index f79223e..c2fb1ab 100644 --- a/content/checkout/core-resources/transactions.md +++ b/content/checkout/core-resources/transactions.md @@ -2,78 +2,49 @@ date: 2018-09-17T15:21:22+02:00 title: Transactions description: Transaction resources. -weight: 3 +weight: 4 --- -Transactions are a way to manage value on and between accounts in the Plue wallet. Every transaction can be either a `debit` or a `credit`. In simple terms `debit` reduces an account's balance and a `credit` increases an account's balance. A transfer can be thought of as a 2-step transaction where one user is debited and another is credited the required amount. This structure allows for easy verification of balances and can be used to back track to a specific point in time to discover what the balance was. - -Every transaction has a status that can be used to gauge the state of the transaction. The statuses are: - -status | description ----|--- -Initiating | processing the transaction insert -Pending | the transaction has passed all validation -Complete | the transaction has been applied to the account currency's balance. -Failed | the transaction and the balance have been reverted +A Transaction object returned matches the structure of a Plue transaction. Below is the example: ### Object -Transactions are essentially logs of actions on an account balance. With this in mind, transactions contain information that can be used to identify who made the transaction, what the transaction was made on, and how the transaction impacted the account. - -A full transaction object looks like: - -```json +``` { - "status": "success", - "data": { - "id": "00000000-0000-0000-0000-000000000000", - "tx_type": "credit", - "subtype": null, - "note": "", - "metadata": {}, - "status": "Pending", - "reference": null, - "amount": 500, - "fee": 0, - "total_amount": 500, - "balance": 0, - "account": "0000000000", - "label": "Credit", - "company": "plue_prod", - "currency": { - "description": "Rand", - "code": "ZAR", - "symbol": "R", - "unit": "rand", - "divisibility": 2 + "rehive_code": "459b3407-3009-4f77-bbbf-5d6e12788958", + "settled": false, + "payment_processor_quote": 14, + "details": { + "id": "459b3407-3009-4f77-bbbf-5d6e12788958", + "collection": "b9c56ace-7dd8-49f6-ba79-04cd9d3314d2", + "tx_type": "credit", + "subtype": "deposit_crypto", + "note": "", + "metadata": { + "service_payment_requests": { + "request_id": "deb62287-dbc6-4f11-8f83-d753f6cf1284", + "payer_email": "customer@plue.com", + "payer_mobile": "+27768507683", + "sender_identifier": "fbb59810-04ab-401a-a017-d293dfa5c7c5" + }, + "service_bitcoin": { + "confirmations": "0", + "tx_hash": "", }, - "source_transaction": null, - "destination_transaction": null, - "messages": [], - "fees": [], - "created": 1476691969394, - "updated": 1496135465287 + }, + "status": "Pending", + "reference": null, + "amount": 200, + "fee": 0, + "total_amount": 200, + "account": "24AX64NGEJ", + "label": "Crypto currency deposit", + "company": "prs_production", + "destination_transaction": null, + "fees": [], + "archived": false, + "created": 1596795344112, + "updated": 1596795346496 } } ``` - -A debit transaction will look much the same as the above, except the `amount` will be a negative value and the `tx_type` will be `Debit`. - -On the other hand a transfer will have some additional information in the `source_transaction` or `destination_transaction` attributes. As stated previously, transfers are simply debits/credits themselves. So, if a transfer is made between two accounts 2 transactions will be created: - -1. A debit transaction reducing the balance of the sender. In addition the `destination_transaction` attribute will be populated with a pointer to the receiver transaction. -2. A credit transaction increasing the balance of the receiver. In addition the `source_transaction` attribute will be populated with a pointer to the sender transaction. - -### Endpoints - -section | type| URL | methods ----|---|---|--- -user | multiple | `https://api.plue.io/3/transactions/` | `GET`, `POST` -user | single | `https://api.plue.io/3/transactions//` | `GET`, `PUT`,`PATCH` -user | single | `https://api.plue.io/3/transactions/transfer/` | `POST` -user | single | `https://api.plue.io/3/transactions/debit/` | `POST` -user | single | `https://api.plue.io/3/transactions/credit/` | `POST` - -### Usage - -Usage remains the same for all endpoints in Plue. Simply invoke one of the allowed HTTP methods with the correct `Content-Type` and a `Authorization` header. diff --git a/content/checkout/core-resources/users.md b/content/checkout/core-resources/users.md deleted file mode 100644 index 43aa004..0000000 --- a/content/checkout/core-resources/users.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Users -description: User resources. -weight: 1 ---- - -### Object - -This object is returned together with the authentication token when the user logs in. The full user object looks like this: - -```json -{ - "id": "00000000-0000-0000-0000-000000000000", - "first_name": "Joe", - "last_name": "Soap", - "email": "joe@example.com", - "username": null, - "id_number": "", - "birth_date": "2000-01-01", - "profile": null, - "currency": { - "description": "Rand", - "code": "ZAR", - "symbol": "R", - "unit": "rand", - "divisibility": 2 - }, - "company": "plue_prod", - "language": "en", - "nationality": "ZA", - "metadata": null, - "mobile": "+27840000000", - "timezone": "Asia/Dhaka", - "verified": true, - "verification": { - "email": true, - "mobile": true - }, - "kyc": { - "updated": 1509539801040, - "status": "pending" - }, - "status": "pending", - "groups": [], - "permissions": [], - "created": 1464912953000, - "updated": 1464912953000, - "settings": { - "allow_transactions": true, - "allow_debit_transactions": true, - "allow_credit_transactions": true - }, - "last_login": null, - "archived": false -} -``` - -### Endpoints - -section | type| URL | methods ----|---|---|--- -auth | single | `https://api.plue.io/3/user/` | `GET`, `PUT`,`PATCH` -auth | single | `https://api.plue.io/3/auth/register/` | `POST` -auth | single | `https://api.plue.io/3/auth/login/` | `POST` -auth | single | `https://api.plue.io/3/auth/logout/` | `POST` - - -### Usage - -Usage remains the same for all endpoints. Simply invoke one of the allowed HTTP methods with the correct `Content-Type` and a `Authorization` header if required. diff --git a/content/checkout/custom-integration/_index.md b/content/checkout/custom-integration/_index.md new file mode 100644 index 0000000..83945d4 --- /dev/null +++ b/content/checkout/custom-integration/_index.md @@ -0,0 +1,6 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Custom Integration +description: Custom integration guide. +weight: 3 +--- diff --git a/content/checkout/custom-integration/closed-loop.md b/content/checkout/custom-integration/closed-loop.md new file mode 100644 index 0000000..1e2a518 --- /dev/null +++ b/content/checkout/custom-integration/closed-loop.md @@ -0,0 +1,41 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 5. Closed-loop +description: Handling Closed-loop payment processors +weight: 5 +--- + +Closed-loop payments involve the user paying directly from their wallet balance to your merchant account. There are a few options available to the ender user but each work in a very similar way. The options you should present to the user if they chose to pay with their wallet balance are as follows, any can be omitted depending on what you would like to support: + +### Scan to Pay and Login to Pay +To be added. + +### OTP payment + +An OTP payment is one that is authorized by a single use OTP code that is sent to a user authorized mobile number. + +The required information from the user is: +1. An email address +2. A mobile number that validated on their wallet + +Once the user has provided this information you will need to PATCH the Invoice as follows: +``` +curl -X PATCH "/requests//" -H "accept: application/json" +-H "Content-Type: application/json" +-d "{ \"payer_email\": \"user@example.com\", \"payer_mobile_number\": \"+27777777777\"}" +``` + +If successful the user will receive an SMS with the OTP code. You will need to provide a way for the user to enter this code so you can make a POST request to: `/manager/businesses//invoice//otp-challenge` as follows: +``` +curl -X POST "/requests//otp_challenge/" +-H "accept: application/json" -H "Content-Type: application/json" --data '{"otp": "401703"}' +``` + +This is a simple Success/Response endpoint. On a successful 201 response a transfer will be created automatically between you and the user. Any errors will need to be forwarded to the end user. + + + + + + + diff --git a/content/checkout/custom-integration/invoicing.md b/content/checkout/custom-integration/invoicing.md new file mode 100644 index 0000000..66465f1 --- /dev/null +++ b/content/checkout/custom-integration/invoicing.md @@ -0,0 +1,87 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 1. Invoicing +description: Creating an invoice for a payment +weight: 2 +--- + +An invoice encapsulates the entire payments process. Once the customer has selected Plue as a payment option the next step is for your system to generate a Plue invoice for their payment. + +### Create the invoice +The first step to initiate the payment process is to create an invoice. This would usually be done once the user has selected Plue as the payment option for the order they wish to pay for. + +##### The core pieces of information required to create an invoice are: +1. The total amount to be paid in your base currency +2. Return url: When the user has completed their off-site payment this is the url they should be redirected back to. +3. An optional “reference” field which ideally should match an identifier for your order within your e-commerce system +4. Status: The status of the invoice which should be set to “initiated” + + +### Endpoints +URL | methods +---|--- +`​/manager​/businesses​/{business_id}​/invoices​/` | `POST` + +### Example data: +``` +{ + "request_reference": "MY_ECOMMERCE_REFERENCE", + "request_amount": 10000, # Value of invoice in cents + "description": "Online payment for clothes", # Optional description text + "status": "initiated", + "return_url": "https://my-ecommerce-store.com/order/", +} + +``` + +### Example success response: +``` +{ + "id": "e7d7a5a2-9a97-4930-a992-589a6133488f", + "user": "{}", # User object + "account": "string", + "request_reference": "MY_ECOMMERCE_REFERENCE", + "request_currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "request_amount": 10000, + "Primary_payment_processor": “”, + "description": "Online payment for clothes", + "status": "initiated", + "return_url": "https://my-ecommerce-store.com/order/", + "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "payment_processor_quotes": [], + "created": 0, + "updated": 0 +} +``` + +### Redirect customer +Once the invoice has been created the user needs to be redirected to the off-site payments page to handle choosing further payment options and making the payment. This is done after receiving the `redirect_url` field and sending the user directly to this link on successful invoice creation. + +When a user has completed payment they will automatically be directed back to the url defined in the `return_url` field. + + +### Cancelling invoice +In the case where an invoice is no longer valid the status can be PATCH’d using the following endpoint: +### Endpoints +URL | methods +---|--- +`​/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` + +PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. + + + + + + + + + + diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md new file mode 100644 index 0000000..cf24dcc --- /dev/null +++ b/content/checkout/custom-integration/open-loop.md @@ -0,0 +1,108 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 4. Open-loop +description: Handling Open-loop payment processors +weight: 4 +--- + +Open loop payments are any non-wallet balance payments made. These are usually deposits from an external value such as a crypto currency, credit card or bank payment. + +### Displaying payment information +The display of the payment information can depend on how the payment processor handles payments. Each payment processor quote will contain a different set of payment details. The relevant quote to display to the user will be the one with the matching payment processor to the `primary_payment_processor` field. + +Within the quote objects on the Invoice there will be a few fields(NOTE: this reference is different to the Invoice reference): + +``` + "reference": "459b3407-3009-4f77-bbbf-5d6e12788958", + "deposit_details": {}, +``` + +The reference in the open-loop context is the identifying feature for the user to make the payment with this could be: A bank deposit reference they should use, a crypto address they should make a payment too etc. + +The deposit details are any extra information such as: Another unique crypto identifier, bank branch details etc. + +For each open-loop processor you support these two fields should be displayed appropriately to the user paying. Using Bitcoin as an example your Quote fields might look like this: + +``` + "reference": "12CsH7h4ro5R8p3FwEAhKZHUEddz1ZfseV", + "deposit_details": {}, +``` + +The reference is the Bitcoin address generated for this deposit which the user paying will need to make a transaction too. + +### Handling statuses + +##### Processing +The user has chosen a payment processor. In certain open-loop cases you might want to pole the `/manager/businesses//invoices//transactions/` endpoint to check for new deposits being made. This is particularly important in the case of crypto deposits waiting for confirmations. + +##### Paid +If the amount sent by the user matches the quoted amount exactly the entire Invoice will be set to the Paid status. Once this has happened you can assume the funds have been received and processed. Any order statuses on your e-commerce platform can be set to their Completed states. + +##### Overpaid +The user has paid more than the quoted amount. This can be handled by Completing any outstanding orders associated with the payment and then refunding the user with the difference between the Quoted amount and the Paid amount. + +##### Underpaid +An underpaid Invoice will require the user to make another transaction for the remaining balance. The difference in the quote fields of `amount` and `total_paid` should be displayed clearly to the user as well as the deposit details for making the outstanding payment. + +##### Expired +Any requests that expire are no longer usable and a new Invoice will need to be created with the same fields as the expired one. + +### Displaying processing Crypto transactions +One of the unique aspects about cryptocurrency is transactions often need to be confirmed multiple times before they can be considered completely irreversible. This means that a user might make a deposit to pay for an Invoice but the invoice will only Complete once the transaction associated with it Complete/is confirmed. You will want to display this to the user so they know they have a pending successful transaction. + +To display this information you will use the transactions endpoint of the invoice: `/manager/businesses//invoices//transactions/`. + +While an Invoice is in the “Processing” state and a relevant crypto payment processor has been selected such as “native_bitcoin” pole the above endpoint until an non-empty array is returned. + +An example of a request with transactions: + +``` +{ + "status": "success", + "data": [ + { + "rehive_code": "459b3407-3009-4f77-bbbf-5d6e12788958", + "settled": false, + "payment_processor_quote": 14, + "details": { + "id": "459b3407-3009-4f77-bbbf-5d6e12788958", + "collection": "b9c56ace-7dd8-49f6-ba79-04cd9d3314d2", + "tx_type": "credit", + "subtype": "deposit_crypto", + "note": "", + "metadata": { + "service_payment_requests": { + "request_id": "deb62287-dbc6-4f11-8f83-d753f6cf1284", + "payer_email": "customer@plue.com", + "sender_identifier": "fbb59810-04ab-401a-a017-d293dfa5c7c5" + }, + "service_bitcoin": { + "confirmations": "0", + "tx_hash": "", + }, + }, + "status": "Pending", + "reference": null, + "amount": 200, + "fee": 0, + "total_amount": 200, + "account": "24AX64NGEJ", + "label": "Crypto currency deposit", + "company": "plue_prod", + "destination_transaction": null, + "fees": [], + "archived": false, + "created": 1596795344112, + "updated": 1596795346496 + } + } + ] +} +``` + +Within the `metadata` field of the transaction object the relevant payment processor, in this case Bitcoin, will include a section such as `service_bitcoin` that contains both the confirmations and the Bitcoin transaction hash(tx_hash field). When a `Pending` transaction exists in this array both the hash and the confirmations with a message such as “You payment has been detected with confirmations is currently waiting to be confirmed.” + + + + + diff --git a/content/checkout/custom-integration/overview.md b/content/checkout/custom-integration/overview.md new file mode 100644 index 0000000..20e2316 --- /dev/null +++ b/content/checkout/custom-integration/overview.md @@ -0,0 +1,8 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Overview +description: Overview of a custom integration. +weight: 1 +--- + +The custom integration is an advanced method of integration but allows for complete control of the end user experience when they make payments. All user interaction will need to be done via your own front-end coupled with your own backend service that interfaces with the Businesses and Payment Requests API. \ No newline at end of file diff --git a/content/checkout/custom-integration/payment-quotes.md b/content/checkout/custom-integration/payment-quotes.md new file mode 100644 index 0000000..65ded28 --- /dev/null +++ b/content/checkout/custom-integration/payment-quotes.md @@ -0,0 +1,49 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 3. Processor Quotes +description: Displaying and interacting with Payment Processor Quotes +weight: 3 +--- + +Once a payment method has been selected the Invoice will return with a relevant Payment Processor Quote entry in the array field. These objects contain a few things: +1. The amount to be paid by the user after converting to the currency of the payment processor from the requested currency. +2. The currency specified by the user that they will be paying in +3. A `reference` field containing a unique identifier for the payment. Examples would be a Bitcoin address to pay to, a UUID for the internal transaction or a Bank payment reference. +4. Deposit information: extra information that might be required by the end user to make the payment. An example would be Bank deposit details. +5. Conversion quote object containing the rate at which the quote amount was calculated at +6. The total_paid by the user. This is the running total for all deposits made using the quotes information. Once it equals the `amount` field the quote is considered paid. + + +#### Payment processor object example: +``` +{ + "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", + "request": 16, + "reference": "459b3407-3009-4f77-bbbf-5d6e12788958", + "deposit_details": {}, + "payment_processor": { + "id": "19dff821-a349-4bbc-a929-72bf9fcef4d1", + "unique_string_name": "native_otp", + "logo": "", + "name": "Native OTP", + "description": "Pay using a wallet balance via an OTP.", + "currencies": [], + "longest_expiration_time": 0, + }, + "currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "amount": 200, + "total_paid": 200, + "expiration_date": null, + "status": "paid", + "conversion_quote": null +} +``` + +Each quote information set should be handled in a specific way depending on the payment processor that was chosen. Next we will cover Open and Closed loop processor types and how to handle the quote information. diff --git a/content/checkout/custom-integration/payments.md b/content/checkout/custom-integration/payments.md new file mode 100644 index 0000000..1528d9e --- /dev/null +++ b/content/checkout/custom-integration/payments.md @@ -0,0 +1,48 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 2. Payment Options +description: Selecting and viewing different payment options +weight: 3 +--- + +Once an invoice is created the user will need to choose which supported payment option that they would like to use. There are two broad types of options: Closed and Open loop payments. + +Selecting a payment method +Each invoice requires a user to select a valid payment method. A list of supported methods for a specific invoice can be found in the `available_payment_processors` array on the Invoice object. They are uniquely identified by a `unique_string_name` field. This list is also the one you have defined when setting up the Merchant configuration settings. + +#### Payment processor object example: +``` + { + "id": "19dff821-a349-4bbc-a929-72bf9fcef4d1", + "unique_string_name": "native_otp", + "logo": "", + "name": "Native OTP", + "description": "Pay using a wallet balance via an OTP.", + "currencies": [], + "longest_expiration_time": 0, + } +``` + +The user should be presented with a list of these payment processors via a front-end. It has relevant display fields such as the Logo, Name and Description as well as the currencies it supports. + +The only piece of information required from the user is a valid email address to attach to the Invoice. + +Once the user has made their choice and entered an email address your backend or front-end should update the Invoice object by PATCHing the `primary_payment_processor` field with the `unique_string_name` of the payment processor using the anonymous endpoint like so: + +``` +curl -X PATCH "/api/requests//" +-H "accept: application/json" -H "Content-Type: application/json" +-d "{ \"primary_payment_processor\": "native_otp"}" +``` + +Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. + + + + + + + + + + diff --git a/content/checkout/custom-integration/webhooks.md b/content/checkout/custom-integration/webhooks.md new file mode 100644 index 0000000..d14d430 --- /dev/null +++ b/content/checkout/custom-integration/webhooks.md @@ -0,0 +1,84 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 6. Webhooks +description: Handling and processing Invoice webhook data +weight: 6 +--- + +While the user is on the hosted payments page the only way to get updates on payments is to process invoice webhooks. This will need to be done by a service you create and host that can receive and process the webhooks as well as make relevant changes to third party platforms that require status changes when a payment succeeds or fails. + +Before being able to process webhooks you will need to create a webhook via the Merchant management section of the wallet. Here you can specify the URL the webhook will be sent to as well as an optional secret for added security. This will be added to the Authorization header like so: “Authorization: Secret YOUR_SECRET”. + +After being set up a Webhook will be sent each time the Invoice has a Status change. + +### Example Webhook: +``` +{ + “data”: { + "id": "e7d7a5a2-9a97-4930-a992-589a6133488f", + "user": "{}", # User object + "account": "string", + "request_reference": "MY_ECOMMERCE_REFERENCE", + "request_currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "request_amount": 10000, + "Primary_payment_processor": “”, + "description": "Online payment for clothes", + "status": "paid", + "return_url": "https://my-ecommerce-store.com/order/", + "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "payment_processor_quotes": [ + { + "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", + "request": 16, + "reference": "459b3407-3009-4f77-bbbf-5d6e12788958", + "deposit_details": {}, + "payment_processor": { + "id": "19dff821-a349-4bbc-a929-72bf9fcef4d1", + "unique_string_name": "native_otp", + "logo": "", + "name": "Native OTP", + "description": "Pay using a wallet balance via an OTP.", + "currencies": [], + "longest_expiration_time": 0, + }, + "currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "amount": 200, + "total_paid": 200, + "expiration_date": null, + "status": "paid", + "conversion_quote": null + } + ], + "created": 0, + "updated": 0 +} +} +``` + +The most relevant field is the `status` field. On successful payment this will be updated to the `paid` state. Once your service receives a webhook with the `paid` status any orders made by the user can be completed on your third party e-commerce platform. + +Another new field is the `payment_processor_quotes` array. This will contain a list of methods chosen by the user to make the payment. It can be used to check what currencies your users are paying or if they over/underpaid and by what amount. + + + + + + + + + + diff --git a/content/checkout/get-started/introduction.md b/content/checkout/get-started/introduction.md index 805a8a8..476b1e0 100644 --- a/content/checkout/get-started/introduction.md +++ b/content/checkout/get-started/introduction.md @@ -5,30 +5,16 @@ description: Introduction to the platform. weight: 1 --- -The Merchant API allows you to integrate the Plue wallet into your existing checkout flow. +The Merchant Documentation helps you to integrate Plue payment processing closed-loop or open-loop wallets for online checkout. -### The API +### Online checkouts -The API is organized around RESTful principles. There are 2 primary sections to the merchant API: +You can either implement a custom payment integration on your existing website or redirect the customer to a hosted payment page. -#### Auth +It is required to integrate the payment selection on your website for the customer to specify their preferred payment method for various providers that you might support. Once the customer proceeds to make a payment, your system will need to create an invoice by sending the order information to the API. You will need to rely on your existing order management system to process all invoice webhooks for updating statuses on your system. -The auth section of the platform provides endpoints for handling authentication and other authorization related functions that are common to all users within the platform. +The response will include a redirect link. In the case of using the hosted payment page, the customer can then select from supported payment methods that you can configure upfront. -Authentication endpoints do not require any specific permissions nor are they limited by any other access control. +Once the customer starts the payment process on the hosted payment page the system will create a quote. In the case of a cryptocurrency payment, this quote will only be valid for a limited duration. -Some example endpoints are: - -* `/3/auth/register/` -* `/3/auth/login/` -* `/3/auth/logout/` - -#### User - -The user section of the platform API is designed for end-users. This set of endpoints only exposes a data set that is relevant to the user as an individual within the system. These endpoints can be exposed to end-users and were created to be used without any intermediary services or layers. - -Some examples endpoints are: - -* `/3/user/` -* `/3/accounts/` -* `/3/transactions/` \ No newline at end of file +In the case of the customer returning to the checkout page, the invoice will be canceled and a new invoice should be created. diff --git a/content/checkout/get-started/quick-guide.md b/content/checkout/get-started/quick-guide.md index 68ae5f7..2296f35 100644 --- a/content/checkout/get-started/quick-guide.md +++ b/content/checkout/get-started/quick-guide.md @@ -3,132 +3,4 @@ date: 2018-09-17T15:21:22+02:00 title: Quick guide description: A quick guide to the platform. weight: 2 ---- - -To get started with the API you have a couple options: - -1. You can choose to use the Plue supported JS SDK -2. Integrate the API manually in your choice of language. - -To use the the SDK check for you language in the "references list" in the sidebar. If you instead want to use a language that does not have a Plue supported SDK, a custom implementation should be trivial as the platform uses standard HTTP which is widely supported. - -### Using the API - -The easiest way to get started with the API is to use cURL to make a login request: - -``` -curl https://api.plue.io/3/auth/login/ - -X POST - -H "Content-Type: application/json" - -d '{"user": "joe@example.com", - "company": "plue_prod" - "password": "joe1234"}' -``` - - - -Once you have your own user you can replace the placeholder data in the example JSON object and then fire off the above request. If successful, you should get a response like this: - -```json -{ - "status": "success" - "data": { - "token": "{token}", - "user": { - "id": "00000000-0000-0000-0000-000000000000", - "first_name": "Joe", - "last_name": "Soap", - "email": "joe@example.com", - "username": "", - "id_number": null, - "birth_date": null, - "profile": null, - "currency": null, - "company": "plue_prod", - "language": "en", - "nationality": "CA", - "metadata": {}, - "mobile": "+00000000000", - "timezone": null, - "verified": false, - "status": "pending", - "kyc": { - "updated": 1509539801040, - "status": "pending" - }, - "verification": { - "email": true, - "mobile": true - }, - "groups": [ - { - "name": "test", - "label": "Test" - } - ], - "permissions": [], - "settings": { - "allow_transactions": true, - "allow_debit_transactions": true, - "allow_credit_transactions": true - } - "created": 1464912953000, - "updated": 1464912953000, - } - } -} -``` - -And there you have it, a successful login. The user was validated and authenticated on the platform and an authentication `token` returned. - - - -For example, you may want to get a list of accounts associated to the user: - -``` -curl https://api.plue.io/3/user/accounts/ - -X GET - -H "Authorization: Token {token}" - -H "Content-Type: application/json" -``` - -If you used the `token` you previously retrieved you should get a successful response containing a list of user accounts: - - -```json -[ - { - "name": "default", - "reference": "0000000000", - "primary": true, - "currencies": [ - { - "balance": 10000, - "available_balance": 10000, - "currency": { - "code": "XBT", - "description": "bitcoin", - "symbol": "฿", - "unit": "bitcoin", - "divisibility": 8 - }, - "limits": [], - "fees": [], - "settings": { - "allow_transactions": true, - "allow_debit_transactions": true, - "allow_credit_transactions": true - }, - "active": true - } - ], - "created": 1464858068745, - "updated": 1464858068745 - } -] - -``` \ No newline at end of file +--- \ No newline at end of file diff --git a/content/checkout/hosted-payments-page/_index.md b/content/checkout/hosted-payments-page/_index.md new file mode 100644 index 0000000..aef1454 --- /dev/null +++ b/content/checkout/hosted-payments-page/_index.md @@ -0,0 +1,6 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Hosted Integration +description: How to integrate the Plue hosted payments page into your existing payments flow +weight: 1 +--- diff --git a/content/checkout/hosted-payments-page/invoicing.md b/content/checkout/hosted-payments-page/invoicing.md new file mode 100644 index 0000000..66465f1 --- /dev/null +++ b/content/checkout/hosted-payments-page/invoicing.md @@ -0,0 +1,87 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 1. Invoicing +description: Creating an invoice for a payment +weight: 2 +--- + +An invoice encapsulates the entire payments process. Once the customer has selected Plue as a payment option the next step is for your system to generate a Plue invoice for their payment. + +### Create the invoice +The first step to initiate the payment process is to create an invoice. This would usually be done once the user has selected Plue as the payment option for the order they wish to pay for. + +##### The core pieces of information required to create an invoice are: +1. The total amount to be paid in your base currency +2. Return url: When the user has completed their off-site payment this is the url they should be redirected back to. +3. An optional “reference” field which ideally should match an identifier for your order within your e-commerce system +4. Status: The status of the invoice which should be set to “initiated” + + +### Endpoints +URL | methods +---|--- +`​/manager​/businesses​/{business_id}​/invoices​/` | `POST` + +### Example data: +``` +{ + "request_reference": "MY_ECOMMERCE_REFERENCE", + "request_amount": 10000, # Value of invoice in cents + "description": "Online payment for clothes", # Optional description text + "status": "initiated", + "return_url": "https://my-ecommerce-store.com/order/", +} + +``` + +### Example success response: +``` +{ + "id": "e7d7a5a2-9a97-4930-a992-589a6133488f", + "user": "{}", # User object + "account": "string", + "request_reference": "MY_ECOMMERCE_REFERENCE", + "request_currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "request_amount": 10000, + "Primary_payment_processor": “”, + "description": "Online payment for clothes", + "status": "initiated", + "return_url": "https://my-ecommerce-store.com/order/", + "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "payment_processor_quotes": [], + "created": 0, + "updated": 0 +} +``` + +### Redirect customer +Once the invoice has been created the user needs to be redirected to the off-site payments page to handle choosing further payment options and making the payment. This is done after receiving the `redirect_url` field and sending the user directly to this link on successful invoice creation. + +When a user has completed payment they will automatically be directed back to the url defined in the `return_url` field. + + +### Cancelling invoice +In the case where an invoice is no longer valid the status can be PATCH’d using the following endpoint: +### Endpoints +URL | methods +---|--- +`​/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` + +PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. + + + + + + + + + + diff --git a/content/checkout/hosted-payments-page/overview.md b/content/checkout/hosted-payments-page/overview.md new file mode 100644 index 0000000..36fb9b0 --- /dev/null +++ b/content/checkout/hosted-payments-page/overview.md @@ -0,0 +1,23 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: Overview +description: Summary of the hosted payments option +weight: 1 +--- + +The hosted option allows for minimal integration to get started with receiving payments from customers. All user interaction for selecting and viewing invoice information will be handled on the hosted invoice page. + +### The basic flow + +1. A customer will select Plue as the payment option +2. An invoice is generated with a link to redirect the user to the hosted payments page +3. The customer is redirected to the hosted page which handles the selection and display of payment options +4. Once the payment has been processed the hosted payments page will redirect the user back if specified +5. A webhook is sent to any relevant services when the Invoice has been completed. + + + + + + + diff --git a/content/checkout/hosted-payments-page/webhooks.md b/content/checkout/hosted-payments-page/webhooks.md new file mode 100644 index 0000000..a4640ee --- /dev/null +++ b/content/checkout/hosted-payments-page/webhooks.md @@ -0,0 +1,84 @@ +--- +date: 2018-09-17T15:21:22+02:00 +title: 2. Webhooks +description: Handling and processing Invoice webhook data +weight: 3 +--- + +While the user is on the hosted payments page the only way to get updates on payments is to process invoice webhooks. This will need to be done by a service you create and host that can receive and process the webhooks as well as make relevant changes to third party platforms that require status changes when a payment succeeds or fails. + +Before being able to process webhooks you will need to create a webhook via the Merchant management section of the wallet. Here you can specify the URL the webhook will be sent to as well as an optional secret for added security. This will be added to the Authorization header like so: “Authorization: Secret YOUR_SECRET”. + +After being set up a Webhook will be sent each time the Invoice has a Status change. + +### Example Webhook: +``` +{ + “data”: { + "id": "e7d7a5a2-9a97-4930-a992-589a6133488f", + "user": "{}", # User object + "account": "string", + "request_reference": "MY_ECOMMERCE_REFERENCE", + "request_currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "request_amount": 10000, + "Primary_payment_processor": “”, + "description": "Online payment for clothes", + "status": "paid", + "return_url": "https://my-ecommerce-store.com/order/", + "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "payment_processor_quotes": [ + { + "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", + "request": 16, + "reference": "459b3407-3009-4f77-bbbf-5d6e12788958", + "deposit_details": {}, + "payment_processor": { + "id": "19dff821-a349-4bbc-a929-72bf9fcef4d1", + "unique_string_name": "native_otp", + "logo": "", + "name": "Native OTP", + "description": "Pay using a wallet balance via an OTP.", + "currencies": [], + "longest_expiration_time": 0, + }, + "currency": { + "code": "USD", + "display_code": "USD", + "description": "United States Dollar", + "symbol": "$", + "unit": "dollar", + "divisibility": 2 + }, + "amount": 200, + "total_paid": 200, + "expiration_date": null, + "status": "paid", + "conversion_quote": null + } + ], + "created": 0, + "updated": 0 +} +} +``` + +The most relevant field is the `status` field. On successful payment this will be updated to the `paid` state. Once your service receives a webhook with the `paid` status any orders made by the user can be completed on your third party e-commerce platform. + +Another new field is the `payment_processor_quotes` array. This will contain a list of methods chosen by the user to make the payment. It can be used to check what currencies your users are paying or if they over/underpaid and by what amount. + + + + + + + + + + diff --git a/content/checkout/integration-guide/_index.md b/content/checkout/integration-guide/_index.md deleted file mode 100644 index c990f3f..0000000 --- a/content/checkout/integration-guide/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Integration guide -description: How to integrate Plue into your existing checkout flow. -weight: 1 ---- diff --git a/content/checkout/integration-guide/authentication.md b/content/checkout/integration-guide/authentication.md deleted file mode 100644 index 8b80da4..0000000 --- a/content/checkout/integration-guide/authentication.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: 1. Authentication -description: Authenticating with Plue -weight: 2 ---- - -The customer arrives on your web page in the browser and selects the _Pay with Plue_ checkout option. The customer is prompted to authenticate their Plue account by providing their email and password. - -### Endpoints -URL | methods ----|--- -`https://api.plue.io/3/auth/login/` | `POST` - -### Javascript example code: -``` -plue.auth.login({ - user: "joe@example.com", - company: "plue_prod", - password: "joe1234" -}).then(function(user){ - ... -},function(err){ - ... -}) -``` - - - - The API will return a success response with the user details and the javascript SDK will handle the storing of the authentication token for use on subsequent requests. - - - - - - - - diff --git a/content/checkout/integration-guide/balance.md b/content/checkout/integration-guide/balance.md deleted file mode 100644 index e701dd0..0000000 --- a/content/checkout/integration-guide/balance.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: 2. Balance check -description: Balance check / currency selection -weight: 3 ---- -The customer's account balance is pulled. You can decide if you want to allow the customer to change their preferred account or currency to make a payment. The customer can see their available balance for the selected accounts as well as the currency conversion rate that matches the currency specified in the order. The customer can change the amount they would need to pay in the currency specified in the order and validate the underlying currency amount that will be charged to their account. The customer can see the fee amount that will be charged to their Plue account before completing the purchase. The customer clicks Confirm to proceed. - -### Endpoints -URL | methods ----|--- -`https://api.plue.io/3/accounts/` | `GET` - -### Javascript example code: -``` -plue.accounts.get({filters: filters}).then(function(res){ - ... -},function(err){ - ... -}) -``` - -The `filters` parameter can be used to customize the response. To retrieve all the user's accounts and currencies, leave out the `{filters: filters}` parameter above. - -To retrieve only the user's primary account, set: -``` -filters = {"primary": true} -``` - -To retrieve only a specific currency whithin the user's primary account, set: -``` -filters = {"primary": true, "currency": "XBT"} -``` - - -Example response: - -``` -[ - { - "name": "default", - "reference": "0000000000", - "primary": true, - "currencies": [ - { - "balance": 10000, - "available_balance": 10000, - "currency": { - "code": "XBT", - "description": "bitcoin", - "symbol": "฿", - "unit": "bitcoin", - "divisibility": 8 - }, - "limits": [], - "fees": [], - "settings": { - "allow_transactions": true, - "allow_debit_transactions": true, - "allow_credit_transactions": true - }, - "active": true - } - ], - "created": 1464858068745, - "updated": 1464858068745 - } -] -``` - - - - - - - - - diff --git a/content/checkout/integration-guide/overview.md b/content/checkout/integration-guide/overview.md deleted file mode 100644 index 7d90eb9..0000000 --- a/content/checkout/integration-guide/overview.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Overview -description: Summary of the checkout flow -weight: 1 ---- - -Accepting payments with Plue Checkout is a three step process, with client side and server side actions. - -From your website running in the customer’s browser, Plue securely collects your customer’s authentication details and returns an authentication token. This, along with any other form data, is then submitted by the browser to the Plue server. -Your application can pull the customer’s account balance and let the customer choose a Plue account to make a payment. The customer can confirm the payment details to proceed. -Your server will receive a webhook that includes the transaction details to validate and fulfil the order. - -Using the Plue server directly ensures that no sensitive authentication data is ever stored on your server. - -Create a simple user interface for your customer to select Plue as a payment method on your web page. The steps below describe a suggested checkout flow: - - -**1. Authentication:** -1.1 The customer arrives on your web page in the browser and selects the Pay with Plue checkout option. -1.2 The customer is prompted to authenticate their Plue account by providing their email and password. - -**2. Balance Check / Currency Selection:** -2.1 The customer's account balance is pulled. -2.2 You can decide if you want to allow the customer to change their preferred account or currency to make a payment. -2.3 The customer can see their available balance for the selected accounts -2.4 The customer clicks Confirm to proceed. - -**3. Direct payment and callback processing** -3.1 The transaction is posted to Plue from your client-side code (the post can also be made from server-side code if preferred). -3.2 Plue will trigger a webhook to your server that includes the transaction details to process the rest of your order. -3.3 It is important that your server-side code cross-references the order_id in the metadata and the transaction status before releasing the order. - - - - - diff --git a/content/checkout/integration-guide/payment.md b/content/checkout/integration-guide/payment.md deleted file mode 100644 index c932250..0000000 --- a/content/checkout/integration-guide/payment.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: 3. Payment -description: Payment and callback processing -weight: 4 ---- - -The transaction is posted to Plue from your client-side code (the post can also be made from server-side code if preferred). Plue will trigger a webhook to your server that includes the transaction details to process the rest of your order. It is important that your server-side code cross-references the order_id in the metadata and the transaction status before releasing the order. - -### Endpoints -URL | methods ----|--- -`https://api.plue.io/3/transactions/transfer/` | `POST` - -### Javascript example code: -``` -plue.transactions.createTransfer( -{ - amount: 500, - recipient: "merchant@email-provider.com" -}).then(function(res){ - ... -},function(err){ - ... -``` - -Example response: -``` -{ - "id": "00000000-0000-0000-0000-000000000000", - "tx_type": "debit", - "subtype": null, - "note": "", - "metadata": {}, - "status": "Complete", - "reference": null, - "amount": -500, - "fee": 0, - "total_amount": -500, - "balance": 0, - "account": "0000000000", - "label": "Debit", - "company": "Plue_prod", - "currency": { - "description": "Rand", - "code": "ZAR", - "symbol": "R", - "unit": "rand", - "divisibility": 2 - }, - "source_transaction": null, - "destination_transaction": { - "id": "00000000-0000-0000-0000-000000000000", - "user": { - "id": "00000000-0000-0000-0000-000000000000", - "first_name": "", - "last_name": "", - "email": "merchant@email-provider.com", - "username": "", - "mobile": "", - "profile": null - } - }, - "messages": [], - "fees": [], - "created": 1476691969394, - "updated": 1496135465287 -} -``` - -### Webhook -This will be posted to the server url you configure whenever a payment is made. -``` -{ - "event": "transaction.execute", - "company": "company_id", - "data": { - "id": "00000000-0000-0000-0000-000000000000", - "tx_type": "debit", - "subtype": null, - "note": "", - "metadata": {}, - "status": "Complete", - "reference": null, - "amount": -500, - "fee": 0, - "total_amount": -500, - "balance": 0, - "account": "0000000000", - "label": "Debit", - "company": "plue_prod", - "currency": { - "description": "Rand", - "code": "ZAR", - "symbol": "R", - "unit": "rand", - "divisibility": 2 - }, - "source_transaction": null, - "destination_transaction": { - "id": "00000000-0000-0000-0000-000000000000", - "user": { - "id": "00000000-0000-0000-0000-000000000000", - "first_name": "", - "last_name": "", - "email": "merchant@email-provider.com", - "username": "", - "mobile": "", - "profile": null - } - }, - "messages": [], - "fees": [], - "created": 1476691969394, - "updated": 1496135465287 - } -} -``` - - - - diff --git a/content/checkout/usage/_index.md b/content/checkout/usage/_index.md deleted file mode 100644 index 460c83f..0000000 --- a/content/checkout/usage/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Usage -description: Platform usage. -weight: 4 ---- diff --git a/content/checkout/usage/authorization.md b/content/checkout/usage/authorization.md deleted file mode 100644 index 594a188..0000000 --- a/content/checkout/usage/authorization.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Authorization -description: Authorization. -weight: 1 ---- - -The API uses a token-based HTTP Authentication scheme. - -Once a user has logged in and received a token, each subsequent request should include the token in the HTTP Authorization header. Tokens expire 10 hours after creation. Once a token has expired, login is required in order to re-authenticate. - -### Authorization Header - -When making requests, the API key should be included as a token in the `Authorization` header: - -```json -Authorization: Token {token} -``` - - diff --git a/content/checkout/usage/errors.md b/content/checkout/usage/errors.md deleted file mode 100644 index 2d60d59..0000000 --- a/content/checkout/usage/errors.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Errors -description: Errors. -weight: 2 ---- - - -When an error occurs in the platform it returns a HTTP response containing two things: - -1. body (formatted in JSON) containing a `message` and `status` -2. and HTTP response code - -The JSON error response always includes a `message` string. If an error occurred as a result of a specific attribute or -key the error details will be outputted in the `data` object. - -Errors will be formatted in one of two ways. A minimal error message: - -```json -{ - "status": "error", - "message": "Error message." -} -``` - -or a descriptive error message including an additional `data` object with details: - -```json - { - "status": "error", - "message": "First error message, Second error message", - "data": { - "field_name1": [ - "First error message." - ], - "field_name2": [ - "Second error message." - ] - } -} -``` diff --git a/content/checkout/usage/events.md b/content/checkout/usage/events.md deleted file mode 100644 index 412a16d..0000000 --- a/content/checkout/usage/events.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Events -description: Events. -weight: 6 ---- - -The platform has a collection of internal events that can be configured to trigger webhooks. - -Webhooks should always be created with a secure `secret` key. The secret key can be used to identify valid requests to your server. The secret is sent in the Authorization header of the webhook request. - -The platform expects a `200 OK` HTTP response when webhooks are called. If a 200 response is not returned, the platform will retry the webhook up to 12 times with a gradually increasing delay between each retry. - -Every webhook includes a body containing a JSON object. - -```json -{ - "id": 1, - "event": "event.name", - "company": "plue_prod", - "data": { - - } -} -``` - -The attributes in the above object are described below: - -Attribute | Description ---- | --- -id | The unique id of the request. This id is shared between retries of the same request. -event | The event that triggered the webhook -company | The company identifier -data | an object contained different data depending on the event - -### Supported events - -The following webhook events are supported: - -Event | Description ---- | --- -`transaction.execute` | transaction executed (complete/failed) event \ No newline at end of file diff --git a/content/checkout/usage/filters.md b/content/checkout/usage/filters.md deleted file mode 100644 index 04720af..0000000 --- a/content/checkout/usage/filters.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Filters -description: Filters. -weight: 4 ---- - -The API provides a way to filter and/or sort on listing pages. All filtering and sorting is done via query parameters in the GET request. - -To filter by a field, include it in the URL as a standard query parameter with a `?` delimiting the URL and the start of the query parameters and a `&` between each filtered field. This can be seen below: - -```shell -curl https://api.plue.io/3/admin/transactions/?status=complete&tx_type=debit&orderby=created - -X GET - -H "Authorization: Token {token}" - -H "Content-Type: application/json" -``` - -To sort results, an endpoint will often also include an optional `orderby` query parameter. - -### Complex Filter Fields - -There are several filter field types in the API that offer more complex interactions: - -#### Date Fields - -Date fields can be further narrowed down by filtering on ranges using the greater -than (`__gt`) and less than (`__lt`) suffixes (eg. `created__gt`). - -#### Metadata Fields - -Custom metadata fields can be filtered on their first level children by adding the child attribute as a suffix (`__child_attribute`). So if metadata contains a JSON object with an attribute `name` it can -be filtered using `?metadata__name=joshua`. diff --git a/content/checkout/usage/idempotency.md b/content/checkout/usage/idempotency.md deleted file mode 100644 index 82a63ae..0000000 --- a/content/checkout/usage/idempotency.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Idempotency -description: Idempotency. -weight: 5 ---- - -The API supports idempotent requests for ensuring the same operations never occur twice. - -To perform an idempotent request, attach a unique key to any `POST`, `PUT` or `PATCH` request made to the API: via the `Idempotency-Key: {key}` header: - -```shell -curl {url} - -X GET - -H "Idempotency-Key: {key}" - -H "Authorization: Token {token}" - -H "Content-Type: application/json" -``` - -API requests made with a new key will get saved along with their HTTP response. Follow up requests made with the same key will always return the same response (As long as the request has the same HTTP method and URL path). The keys (and their associated saved responses) expire after 24 hours. - - diff --git a/content/checkout/usage/pagination.md b/content/checkout/usage/pagination.md deleted file mode 100644 index 3210c5b..0000000 --- a/content/checkout/usage/pagination.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Pagination -description: Pagination. -weight: 3 ---- - -On listing pages, the API provides a way to paginate results. The default pagination method offered by the API is offset pagination, which allows navigation to an arbitrary point in a list of results as well as via `next` and `prev`attributes. The JSON format returned on paginated listing pages looks like this: - -```shell - { - "status": "success", - "data": { - "count": 1, - "next": null, - "previous": null, - "results": [] - } -} -``` - -The default page size is 15 but can be changed by adding a `page_size` query parameter to the request URL. From b205eae52ccdd8fea76f946c4f77cac9f9c4c58a Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Fri, 21 Aug 2020 15:52:47 +0200 Subject: [PATCH 09/19] Removed quick guide --- content/checkout/get-started/quick-guide.md | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 content/checkout/get-started/quick-guide.md diff --git a/content/checkout/get-started/quick-guide.md b/content/checkout/get-started/quick-guide.md deleted file mode 100644 index 2296f35..0000000 --- a/content/checkout/get-started/quick-guide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -date: 2018-09-17T15:21:22+02:00 -title: Quick guide -description: A quick guide to the platform. -weight: 2 ---- \ No newline at end of file From 5a582da87614245968d5ecb248a575718f7e80df Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Fri, 21 Aug 2020 16:11:16 +0200 Subject: [PATCH 10/19] Updated gitignore and old yaml config to match new rdeploy setup --- .gitignore | 1 + rdeploy.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 3bee02f..2f708a5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ /public resources/_gen/ .env +opt *.DS_Store diff --git a/rdeploy.yaml b/rdeploy.yaml index ff96267..5fb4c30 100644 --- a/rdeploy.yaml +++ b/rdeploy.yaml @@ -9,3 +9,5 @@ configs: helm_chart: rehive/rehive-service helm_chart_version: 0.2.2 helm_values_path: ./etc/helm/production/values.yaml + helm_version: 2.14.3 + use_system_helm: false \ No newline at end of file From 5bd5aeb16e27832a7be8f3bff4a4fa6f5295a5f1 Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Fri, 18 Dec 2020 09:57:07 +0200 Subject: [PATCH 11/19] Removed rehive references --- content/checkout/custom-integration/webhooks.md | 2 +- content/checkout/hosted-payments-page/webhooks.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/checkout/custom-integration/webhooks.md b/content/checkout/custom-integration/webhooks.md index d14d430..fa73343 100644 --- a/content/checkout/custom-integration/webhooks.md +++ b/content/checkout/custom-integration/webhooks.md @@ -32,7 +32,7 @@ After being set up a Webhook will be sent each time the Invoice has a Status cha "description": "Online payment for clothes", "status": "paid", "return_url": "https://my-ecommerce-store.com/order/", - "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "redirect_url": "https://app.rehive.com/checkout/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", "payment_processor_quotes": [ { "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", diff --git a/content/checkout/hosted-payments-page/webhooks.md b/content/checkout/hosted-payments-page/webhooks.md index a4640ee..81ca4b1 100644 --- a/content/checkout/hosted-payments-page/webhooks.md +++ b/content/checkout/hosted-payments-page/webhooks.md @@ -32,7 +32,7 @@ After being set up a Webhook will be sent each time the Invoice has a Status cha "description": "Online payment for clothes", "status": "paid", "return_url": "https://my-ecommerce-store.com/order/", - "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "redirect_url": "https://app.plue.com/checkout/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", "payment_processor_quotes": [ { "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", From e673da22cc18dca3d567d7ddadeff193f44201ac Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Fri, 18 Dec 2020 10:01:24 +0200 Subject: [PATCH 12/19] Fix merge issue references --- content/checkout/core-resources/payment-processor.md | 4 ++-- content/checkout/core-resources/transactions.md | 2 +- content/checkout/custom-integration/open-loop.md | 2 +- content/checkout/custom-integration/webhooks.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/checkout/core-resources/payment-processor.md b/content/checkout/core-resources/payment-processor.md index 5a4e664..1368e02 100644 --- a/content/checkout/core-resources/payment-processor.md +++ b/content/checkout/core-resources/payment-processor.md @@ -22,7 +22,7 @@ Each payment processor has a unique subtype and identifier field "description": "Pay using a wallet balance.", "currencies": [], "longest_expiration_time": 0, - "rehive_transaction_identifier": null, - "rehive_subtype": "receive_email" + "transaction_identifier": null, + "transaction_subtype": "receive_email" } ``` diff --git a/content/checkout/core-resources/transactions.md b/content/checkout/core-resources/transactions.md index c2fb1ab..75585a3 100644 --- a/content/checkout/core-resources/transactions.md +++ b/content/checkout/core-resources/transactions.md @@ -11,7 +11,7 @@ A Transaction object returned matches the structure of a Plue transaction. Below ``` { - "rehive_code": "459b3407-3009-4f77-bbbf-5d6e12788958", + "transaction_code": "459b3407-3009-4f77-bbbf-5d6e12788958", "settled": false, "payment_processor_quote": 14, "details": { diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md index cf24dcc..8575809 100644 --- a/content/checkout/custom-integration/open-loop.md +++ b/content/checkout/custom-integration/open-loop.md @@ -61,7 +61,7 @@ An example of a request with transactions: "status": "success", "data": [ { - "rehive_code": "459b3407-3009-4f77-bbbf-5d6e12788958", + "transaction_code": "459b3407-3009-4f77-bbbf-5d6e12788958", "settled": false, "payment_processor_quote": 14, "details": { diff --git a/content/checkout/custom-integration/webhooks.md b/content/checkout/custom-integration/webhooks.md index fa73343..7791099 100644 --- a/content/checkout/custom-integration/webhooks.md +++ b/content/checkout/custom-integration/webhooks.md @@ -32,7 +32,7 @@ After being set up a Webhook will be sent each time the Invoice has a Status cha "description": "Online payment for clothes", "status": "paid", "return_url": "https://my-ecommerce-store.com/order/", - "redirect_url": "https://app.rehive.com/checkout/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "redirect_url": "https://app.plue.com/checkout/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", "payment_processor_quotes": [ { "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", From e74eeeb8e5bbea47a2926f15322fd39fa6ef512e Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Tue, 30 Mar 2021 14:15:59 +0200 Subject: [PATCH 13/19] Update open-loop.md --- content/checkout/custom-integration/open-loop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md index 8575809..e9673b4 100644 --- a/content/checkout/custom-integration/open-loop.md +++ b/content/checkout/custom-integration/open-loop.md @@ -33,7 +33,7 @@ The reference is the Bitcoin address generated for this deposit which the user p ### Handling statuses ##### Processing -The user has chosen a payment processor. In certain open-loop cases you might want to pole the `/manager/businesses//invoices//transactions/` endpoint to check for new deposits being made. This is particularly important in the case of crypto deposits waiting for confirmations. +The user has chosen a payment processor. In certain open-loop cases you might want to poll the `/manager/businesses//invoices//transactions/` endpoint to check for new deposits being made. This is particularly important in the case of crypto deposits waiting for confirmations. ##### Paid If the amount sent by the user matches the quoted amount exactly the entire Invoice will be set to the Paid status. Once this has happened you can assume the funds have been received and processed. Any order statuses on your e-commerce platform can be set to their Completed states. From 8d35a367ddc4a0ceea238467f23128ec2aeeb099 Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Tue, 6 Apr 2021 18:00:18 +0200 Subject: [PATCH 14/19] Updated the base domains on api calls in docs --- content/checkout/core-resources/invoice.md | 2 +- content/checkout/custom-integration/closed-loop.md | 4 ++-- content/checkout/custom-integration/invoicing.md | 4 ++-- content/checkout/custom-integration/open-loop.md | 2 +- content/checkout/custom-integration/payments.md | 4 ++-- content/checkout/hosted-payments-page/invoicing.md | 2 +- content/checkout/hosted-payments-page/webhooks.md | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/content/checkout/core-resources/invoice.md b/content/checkout/core-resources/invoice.md index 918ba70..a173e2d 100644 --- a/content/checkout/core-resources/invoice.md +++ b/content/checkout/core-resources/invoice.md @@ -47,7 +47,7 @@ cancelled | The invoice has been set to cancelled by a manager. "metadata": null, "status": "overpaid", "account": null, - "redirect_url": "?request=deb62287-dbc6-4f11-8f83-d753f6cf1284", + "redirect_url": "http://wallet.plue.com/checkout?request=deb62287-dbc6-4f11-8f83-d753f6cf1284", "payer_email": "customer@plue.com", "return_url": null, "payment_processor_quotes": [ diff --git a/content/checkout/custom-integration/closed-loop.md b/content/checkout/custom-integration/closed-loop.md index 1e2a518..dd1429c 100644 --- a/content/checkout/custom-integration/closed-loop.md +++ b/content/checkout/custom-integration/closed-loop.md @@ -25,9 +25,9 @@ curl -X PATCH "/requests//" -H "accept: application/json" -d "{ \"payer_email\": \"user@example.com\", \"payer_mobile_number\": \"+27777777777\"}" ``` -If successful the user will receive an SMS with the OTP code. You will need to provide a way for the user to enter this code so you can make a POST request to: `/manager/businesses//invoice//otp-challenge` as follows: +If successful the user will receive an SMS with the OTP code. You will need to provide a way for the user to enter this code so you can make a POST request to: `https://api.invoices.plue.io/requests//otp_challenge/` as follows: ``` -curl -X POST "/requests//otp_challenge/" +curl -X POST "https://api.invoices.plue.io/requests//otp_challenge/" -H "accept: application/json" -H "Content-Type: application/json" --data '{"otp": "401703"}' ``` diff --git a/content/checkout/custom-integration/invoicing.md b/content/checkout/custom-integration/invoicing.md index 66465f1..703294b 100644 --- a/content/checkout/custom-integration/invoicing.md +++ b/content/checkout/custom-integration/invoicing.md @@ -54,7 +54,7 @@ URL | methods "description": "Online payment for clothes", "status": "initiated", "return_url": "https://my-ecommerce-store.com/order/", - "redirect_url": "https://.com/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "redirect_url": "https://wallet.plue.io/checkout?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", "payment_processor_quotes": [], "created": 0, "updated": 0 @@ -72,7 +72,7 @@ In the case where an invoice is no longer valid the status can be PATCH’d usin ### Endpoints URL | methods ---|--- -`​/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` +`​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md index e9673b4..2ee1796 100644 --- a/content/checkout/custom-integration/open-loop.md +++ b/content/checkout/custom-integration/open-loop.md @@ -50,7 +50,7 @@ Any requests that expire are no longer usable and a new Invoice will need to be ### Displaying processing Crypto transactions One of the unique aspects about cryptocurrency is transactions often need to be confirmed multiple times before they can be considered completely irreversible. This means that a user might make a deposit to pay for an Invoice but the invoice will only Complete once the transaction associated with it Complete/is confirmed. You will want to display this to the user so they know they have a pending successful transaction. -To display this information you will use the transactions endpoint of the invoice: `/manager/businesses//invoices//transactions/`. +To display this information you will use the transactions endpoint of the invoice: `https:/api.business.plue.io/manager/businesses//invoices//transactions/`. While an Invoice is in the “Processing” state and a relevant crypto payment processor has been selected such as “native_bitcoin” pole the above endpoint until an non-empty array is returned. diff --git a/content/checkout/custom-integration/payments.md b/content/checkout/custom-integration/payments.md index 1528d9e..c5f20fd 100644 --- a/content/checkout/custom-integration/payments.md +++ b/content/checkout/custom-integration/payments.md @@ -30,12 +30,12 @@ The only piece of information required from the user is a valid email address to Once the user has made their choice and entered an email address your backend or front-end should update the Invoice object by PATCHing the `primary_payment_processor` field with the `unique_string_name` of the payment processor using the anonymous endpoint like so: ``` -curl -X PATCH "/api/requests//" +curl -X PATCH "https:/api.invoices.plue.io/api/requests//" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"primary_payment_processor\": "native_otp"}" ``` -Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. +Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `https:/api.business.plue.io/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. diff --git a/content/checkout/hosted-payments-page/invoicing.md b/content/checkout/hosted-payments-page/invoicing.md index 66465f1..88ecdc1 100644 --- a/content/checkout/hosted-payments-page/invoicing.md +++ b/content/checkout/hosted-payments-page/invoicing.md @@ -72,7 +72,7 @@ In the case where an invoice is no longer valid the status can be PATCH’d usin ### Endpoints URL | methods ---|--- -`​/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` +`​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. diff --git a/content/checkout/hosted-payments-page/webhooks.md b/content/checkout/hosted-payments-page/webhooks.md index 81ca4b1..6016f3c 100644 --- a/content/checkout/hosted-payments-page/webhooks.md +++ b/content/checkout/hosted-payments-page/webhooks.md @@ -32,7 +32,7 @@ After being set up a Webhook will be sent each time the Invoice has a Status cha "description": "Online payment for clothes", "status": "paid", "return_url": "https://my-ecommerce-store.com/order/", - "redirect_url": "https://app.plue.com/checkout/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", + "redirect_url": "https://wallet.plue.com/checkout/?request=e7d7a5a2-9a97-4930-a992-589a6133488f&return_url=https://my-ecommerce-store.com/order/", "payment_processor_quotes": [ { "id": "27fd41af-279e-44e7-b384-d6a6fe54f160", From 7d7d4642428ad7545a443d50c5f2181af1ea65ba Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Tue, 6 Apr 2021 21:56:56 +0200 Subject: [PATCH 15/19] Added domains to missing endpoints --- content/checkout/custom-integration/closed-loop.md | 2 +- content/checkout/custom-integration/invoicing.md | 2 +- content/checkout/hosted-payments-page/invoicing.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/checkout/custom-integration/closed-loop.md b/content/checkout/custom-integration/closed-loop.md index dd1429c..d1703aa 100644 --- a/content/checkout/custom-integration/closed-loop.md +++ b/content/checkout/custom-integration/closed-loop.md @@ -20,7 +20,7 @@ The required information from the user is: Once the user has provided this information you will need to PATCH the Invoice as follows: ``` -curl -X PATCH "/requests//" -H "accept: application/json" +curl -X PATCH "https://api.invoices.plue.io/requests//" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"payer_email\": \"user@example.com\", \"payer_mobile_number\": \"+27777777777\"}" ``` diff --git a/content/checkout/custom-integration/invoicing.md b/content/checkout/custom-integration/invoicing.md index 703294b..1f017f0 100644 --- a/content/checkout/custom-integration/invoicing.md +++ b/content/checkout/custom-integration/invoicing.md @@ -20,7 +20,7 @@ The first step to initiate the payment process is to create an invoice. This wou ### Endpoints URL | methods ---|--- -`​/manager​/businesses​/{business_id}​/invoices​/` | `POST` +`​​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` ### Example data: ``` diff --git a/content/checkout/hosted-payments-page/invoicing.md b/content/checkout/hosted-payments-page/invoicing.md index 88ecdc1..eb7f43c 100644 --- a/content/checkout/hosted-payments-page/invoicing.md +++ b/content/checkout/hosted-payments-page/invoicing.md @@ -20,7 +20,7 @@ The first step to initiate the payment process is to create an invoice. This wou ### Endpoints URL | methods ---|--- -`​/manager​/businesses​/{business_id}​/invoices​/` | `POST` +`​​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` ### Example data: ``` From 48110710465f6fe931d2b65b6f8c0ebd5cac6fbf Mon Sep 17 00:00:00 2001 From: Michail Brynard Date: Thu, 8 Apr 2021 09:19:39 +0200 Subject: [PATCH 16/19] Update https typo in urls --- content/checkout/core-resources/invoice.md | 2 +- content/checkout/custom-integration/invoicing.md | 4 ++-- content/checkout/custom-integration/open-loop.md | 2 +- content/checkout/custom-integration/payments.md | 4 ++-- content/checkout/hosted-payments-page/invoicing.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/content/checkout/core-resources/invoice.md b/content/checkout/core-resources/invoice.md index a173e2d..e085aab 100644 --- a/content/checkout/core-resources/invoice.md +++ b/content/checkout/core-resources/invoice.md @@ -47,7 +47,7 @@ cancelled | The invoice has been set to cancelled by a manager. "metadata": null, "status": "overpaid", "account": null, - "redirect_url": "http://wallet.plue.com/checkout?request=deb62287-dbc6-4f11-8f83-d753f6cf1284", + "redirect_url": "https://wallet.plue.com/checkout?request=deb62287-dbc6-4f11-8f83-d753f6cf1284", "payer_email": "customer@plue.com", "return_url": null, "payment_processor_quotes": [ diff --git a/content/checkout/custom-integration/invoicing.md b/content/checkout/custom-integration/invoicing.md index 1f017f0..e652b6c 100644 --- a/content/checkout/custom-integration/invoicing.md +++ b/content/checkout/custom-integration/invoicing.md @@ -20,7 +20,7 @@ The first step to initiate the payment process is to create an invoice. This wou ### Endpoints URL | methods ---|--- -`​​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` +`​​https://api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` ### Example data: ``` @@ -72,7 +72,7 @@ In the case where an invoice is no longer valid the status can be PATCH’d usin ### Endpoints URL | methods ---|--- -`​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` +`​https://api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md index 2ee1796..df50129 100644 --- a/content/checkout/custom-integration/open-loop.md +++ b/content/checkout/custom-integration/open-loop.md @@ -50,7 +50,7 @@ Any requests that expire are no longer usable and a new Invoice will need to be ### Displaying processing Crypto transactions One of the unique aspects about cryptocurrency is transactions often need to be confirmed multiple times before they can be considered completely irreversible. This means that a user might make a deposit to pay for an Invoice but the invoice will only Complete once the transaction associated with it Complete/is confirmed. You will want to display this to the user so they know they have a pending successful transaction. -To display this information you will use the transactions endpoint of the invoice: `https:/api.business.plue.io/manager/businesses//invoices//transactions/`. +To display this information you will use the transactions endpoint of the invoice: `https://api.business.plue.io/manager/businesses//invoices//transactions/`. While an Invoice is in the “Processing” state and a relevant crypto payment processor has been selected such as “native_bitcoin” pole the above endpoint until an non-empty array is returned. diff --git a/content/checkout/custom-integration/payments.md b/content/checkout/custom-integration/payments.md index c5f20fd..7c3ceb3 100644 --- a/content/checkout/custom-integration/payments.md +++ b/content/checkout/custom-integration/payments.md @@ -30,12 +30,12 @@ The only piece of information required from the user is a valid email address to Once the user has made their choice and entered an email address your backend or front-end should update the Invoice object by PATCHing the `primary_payment_processor` field with the `unique_string_name` of the payment processor using the anonymous endpoint like so: ``` -curl -X PATCH "https:/api.invoices.plue.io/api/requests//" +curl -X PATCH "https://api.invoices.plue.io/api/requests//" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"primary_payment_processor\": "native_otp"}" ``` -Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `https:/api.business.plue.io/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. +Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `https://api.business.plue.io/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. diff --git a/content/checkout/hosted-payments-page/invoicing.md b/content/checkout/hosted-payments-page/invoicing.md index eb7f43c..0b37302 100644 --- a/content/checkout/hosted-payments-page/invoicing.md +++ b/content/checkout/hosted-payments-page/invoicing.md @@ -20,7 +20,7 @@ The first step to initiate the payment process is to create an invoice. This wou ### Endpoints URL | methods ---|--- -`​​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` +`​​https://api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` ### Example data: ``` From 216dbaba77fdaac0aa764ce512bb1f0fc2174b84 Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Thu, 8 Apr 2021 10:37:27 +0200 Subject: [PATCH 17/19] Add /api/ segment to docs urls --- content/checkout/custom-integration/closed-loop.md | 6 +++--- content/checkout/custom-integration/invoicing.md | 4 ++-- content/checkout/custom-integration/open-loop.md | 2 +- content/checkout/custom-integration/payments.md | 4 ++-- content/checkout/hosted-payments-page/invoicing.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/content/checkout/custom-integration/closed-loop.md b/content/checkout/custom-integration/closed-loop.md index d1703aa..9027ce5 100644 --- a/content/checkout/custom-integration/closed-loop.md +++ b/content/checkout/custom-integration/closed-loop.md @@ -20,14 +20,14 @@ The required information from the user is: Once the user has provided this information you will need to PATCH the Invoice as follows: ``` -curl -X PATCH "https://api.invoices.plue.io/requests//" -H "accept: application/json" +curl -X PATCH "https://api.invoices.plue.io/api/requests//" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"payer_email\": \"user@example.com\", \"payer_mobile_number\": \"+27777777777\"}" ``` -If successful the user will receive an SMS with the OTP code. You will need to provide a way for the user to enter this code so you can make a POST request to: `https://api.invoices.plue.io/requests//otp_challenge/` as follows: +If successful the user will receive an SMS with the OTP code. You will need to provide a way for the user to enter this code so you can make a POST request to: `https://api.invoices.plue.io/api/requests//otp_challenge/` as follows: ``` -curl -X POST "https://api.invoices.plue.io/requests//otp_challenge/" +curl -X POST "https://api.invoices.plue.io/api/requests//otp_challenge/" -H "accept: application/json" -H "Content-Type: application/json" --data '{"otp": "401703"}' ``` diff --git a/content/checkout/custom-integration/invoicing.md b/content/checkout/custom-integration/invoicing.md index e652b6c..376ddc6 100644 --- a/content/checkout/custom-integration/invoicing.md +++ b/content/checkout/custom-integration/invoicing.md @@ -20,7 +20,7 @@ The first step to initiate the payment process is to create an invoice. This wou ### Endpoints URL | methods ---|--- -`​​https://api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` +`​​https://api.business.plue.io/api/manager​/businesses​/{business_id}​/invoices​/` | `POST` ### Example data: ``` @@ -72,7 +72,7 @@ In the case where an invoice is no longer valid the status can be PATCH’d usin ### Endpoints URL | methods ---|--- -`​https://api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` +`​https://api.business.plue.io/api/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md index df50129..81a50e8 100644 --- a/content/checkout/custom-integration/open-loop.md +++ b/content/checkout/custom-integration/open-loop.md @@ -50,7 +50,7 @@ Any requests that expire are no longer usable and a new Invoice will need to be ### Displaying processing Crypto transactions One of the unique aspects about cryptocurrency is transactions often need to be confirmed multiple times before they can be considered completely irreversible. This means that a user might make a deposit to pay for an Invoice but the invoice will only Complete once the transaction associated with it Complete/is confirmed. You will want to display this to the user so they know they have a pending successful transaction. -To display this information you will use the transactions endpoint of the invoice: `https://api.business.plue.io/manager/businesses//invoices//transactions/`. +To display this information you will use the transactions endpoint of the invoice: `https://api.business.plue.io/api/manager/businesses//invoices//transactions/`. While an Invoice is in the “Processing” state and a relevant crypto payment processor has been selected such as “native_bitcoin” pole the above endpoint until an non-empty array is returned. diff --git a/content/checkout/custom-integration/payments.md b/content/checkout/custom-integration/payments.md index 7c3ceb3..f12a328 100644 --- a/content/checkout/custom-integration/payments.md +++ b/content/checkout/custom-integration/payments.md @@ -30,12 +30,12 @@ The only piece of information required from the user is a valid email address to Once the user has made their choice and entered an email address your backend or front-end should update the Invoice object by PATCHing the `primary_payment_processor` field with the `unique_string_name` of the payment processor using the anonymous endpoint like so: ``` -curl -X PATCH "https://api.invoices.plue.io/api/requests//" +curl -X PATCH "https://api.invoices.plue.io/api/api/requests//" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"primary_payment_processor\": "native_otp"}" ``` -Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `https://api.business.plue.io/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. +Note: because this is an anonymous endpoint either the front or backend can call it but it has very limited interaction but it does allow for the selecting of a payment method. The `https://api.business.plue.io/api/manager/businesses/{business_id}/invoices/{invoice_id}/` endpoint can always be used with a valid authentication token for any other updates required to be made to the invoice. diff --git a/content/checkout/hosted-payments-page/invoicing.md b/content/checkout/hosted-payments-page/invoicing.md index 0b37302..8fdd41e 100644 --- a/content/checkout/hosted-payments-page/invoicing.md +++ b/content/checkout/hosted-payments-page/invoicing.md @@ -20,7 +20,7 @@ The first step to initiate the payment process is to create an invoice. This wou ### Endpoints URL | methods ---|--- -`​​https://api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `POST` +`​​https://api.business.plue.io/api/manager​/businesses​/{business_id}​/invoices​/` | `POST` ### Example data: ``` From 9ca189e528ac834a915e5715ff0e3460124ad5f2 Mon Sep 17 00:00:00 2001 From: Connor Macdougall Date: Thu, 8 Apr 2021 10:42:36 +0200 Subject: [PATCH 18/19] Fix mispelled endpoint --- content/checkout/hosted-payments-page/invoicing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/checkout/hosted-payments-page/invoicing.md b/content/checkout/hosted-payments-page/invoicing.md index 8fdd41e..fc4414d 100644 --- a/content/checkout/hosted-payments-page/invoicing.md +++ b/content/checkout/hosted-payments-page/invoicing.md @@ -72,7 +72,7 @@ In the case where an invoice is no longer valid the status can be PATCH’d usin ### Endpoints URL | methods ---|--- -`​https:/api.business.plue.io/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` +`​​​https://api.business.plue.io/api/manager​/businesses​/{business_id}​/invoices​/` | `PATCH` PATCH the endpoint with the new `cancelled` status and this will stop the user from viewing/interacting with the invoice. From 352468ee464880e3a784cf2ad787f278d79c94a6 Mon Sep 17 00:00:00 2001 From: Michail Brynard Date: Thu, 8 Apr 2021 19:52:09 +0200 Subject: [PATCH 19/19] Update incomplete endpoint --- content/checkout/custom-integration/open-loop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/checkout/custom-integration/open-loop.md b/content/checkout/custom-integration/open-loop.md index 81a50e8..a5b5c5d 100644 --- a/content/checkout/custom-integration/open-loop.md +++ b/content/checkout/custom-integration/open-loop.md @@ -33,7 +33,7 @@ The reference is the Bitcoin address generated for this deposit which the user p ### Handling statuses ##### Processing -The user has chosen a payment processor. In certain open-loop cases you might want to poll the `/manager/businesses//invoices//transactions/` endpoint to check for new deposits being made. This is particularly important in the case of crypto deposits waiting for confirmations. +The user has chosen a payment processor. In certain open-loop cases you might want to poll the `https://api.business.plue.io/api/manager/businesses//invoices//transactions/` endpoint to check for new deposits being made. This is particularly important in the case of crypto deposits waiting for confirmations. ##### Paid If the amount sent by the user matches the quoted amount exactly the entire Invoice will be set to the Paid status. Once this has happened you can assume the funds have been received and processed. Any order statuses on your e-commerce platform can be set to their Completed states.