# Npay Implement Guide(V1)
## Edit history
* 2021/01/07 Npay Implement Guide(V1) released.
* 2021/01/11 add CP must response payload.
* 2021/01/15 add description for every API.
* 2021/01/19 add additionalFields items and encrypt demo code.
* 2021/02/02 add category response in get available pay list API.
## API Domain
* **sandbox:sandbox-api.nppsp.com**
* **production:api.nppsp.com**
## API diagram

## CP provides list
* Does CP need Npay to notify after user creating payment?Yes or No.
## Npay provides list
* AES Key,IV
* api-key
* cpCode
## Npay Restful API
### Npay get available payment API
**description:** This API is for listing available payment mehtod.
* url:{{domain}}/api/v1/payMethods/available
* method:GET
* content-type:application/json
* header:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| api-key | string | 64 | true | Npay povide api-key to cp |
* request url query parameter:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| orderAmt | string | no limit | true | order amount |
| currency | string | 3 | true | pay currency.Plaease check [Currency Support List.](#Currency-Support-List) |
* response status:200
* response body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| payCode | string | 50 | true | available pay method code |
| category | string | 45 | true | available pay method category.Please check [PayMethod Category List.](#PayMethod-Category-List)|
| name | string | 45 | true | available pay method name |
| currency | string | 3 | true | currency code |
| iconUrl | string | no limit | true | pay method icon url |
| additionalFields| array | no limit | true | default is empty array,please check Appendix|
### Npay creat payment API
**description:** This API is for creating a payment.
* url:{{domain}}/api/v1/payment
* method:POST
* content-type:application/json
* header:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| api-key | string | 64 | true | Npay povide api-key to cp |
* body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| data | string | no limit | true | encrypted data |
* encrypt payload:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| cpCode | string | 45 | true | content provider id/company id|
| cpOrderId | string | 45 | true | cp order id,cannot be duplicated|
| cpUserRefId | string | 45 | true | cp user ref id |
| amount | number | (40,2) | true | pay amount |
| currency | string | 3 | true | pay currency |
| payCode | string | 50 | true | pay method code |
| cbUrl | string | 500 | true | callback url for send payment result data to server|
| merchandiseRefId | string | 45 | true | merchandise ref id |
| merchandiseName | string | 45 | true | merchandise name |
| successUrl | string | 500 | true | successful page |
| failedUrl | string | 500 | true | failed page |
| additionalFields | object | no limit | false | Npay get available payment API will response additionalFields if the pay method need.Please check with Appendix.|
**Notice:** Use the AES key to encrypt the payload in JSON format.
* response status:200
* response body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| actionType | number | 1 | true | action type |
| data | string | no limit | true | encrypted data |
**Notice:** Use the AES key to decrypt the data in JSON format.
* decrypt payload:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| paymentId | string | 20 | true | payment id |
| cpOrderId | string | 45 | true | cp order id,cannot be duplicated|
| amount | number | (40,2) | true | pay amount |
| paymentStatus| number | 1 | true | payment status |
| payUrl | string | no limit | true | user pay url |
| orderCreateTimeMs| string | 20 | true | payment create time |
### Notify CP server after creating payment(Optional)
**description:** This is a callback behavior when cp calls creating payment API,npay will notify cp server on the backend.
Npay will notify CP server after creating payment if CP needs.
* url:{{cp cbUrl}}
* method:POST
* content-type:application/json
* request body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| actionType | number | 1 | true | Please check with Action Type Definition of Appendix.|
| data | string | no limit | true | encrypted data.**This is not user paid result.** |
* decrypt payload:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| paymentId | string | 20 | true | payment id |
| cpOrderId | string | 45 | true | cp order id,cannot be duplicated|
| amount | number | (40,2) | true | pay amount |
| paymentStatus| number | 1 | true | payment status |
| payUrl | string | no limit | true | user pay url |
| orderCreateTimeMs| string | 20 | true | payment create time |
**CP must response**
| Column | Type | Value | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| msg | string | RECEIVED | true | example:{"msg":"RECEIVED"},format:JSON |
### Notify CP server after user paid
**description:** This is a callback behavior when user finish the payment ,npay will notify cp server on the backend.
**Notice:If Notify fails,will retry 5 times.(After 1 min,5min,10min,30min,60min)**
* url:{{cp cbUrl}}
* method:POST
* content-type:application/json
* header:none
* body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| actionType | number | 1 | true | Please check with Action Type Definition of Appendix. |
| data | string | no limit | true | encrypted data |
* decrypt payload:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| paymentId | string | 20 | true | payment id |
| cpOrderId | string | 45 | true | cp order id,cannot be duplicated|
| amount | number | (40,2) | true | pay amount |
| paymentStatus| number | 1 | true | payment status |
| orderCreateTimeMs| string | 20 | true | payment create time |
**CP must response**
| Column | Type | Value | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| msg | string | RECEIVED | true | example:{"msg":"RECEIVED"},format:JSON |
### CP get payment result API(Optional)
**description:** This API is for getting payment result from npay.
* url:{{domain}}/api/v1/payment/:paymentId
* method:GET
* content-type:application/json
* header:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| api-key | string | 64 | true | Npay povide api-key to cp |
* response status:200
* response body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| data | string | no limit | true | encrypted data |
* decrypt payload:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| paymentId | string | 20 | true | payment id |
| cpOrderId | string | 45 | true | cp order id,cannot be duplicated|
| amount | number | (40,2) | true | pay amount |
| paymentStatus| number | 1 | true | payment status |
| orderCreateTimeMs| string | 20 | true | payment create time |
### Sync order API(Optional)
**description:** This API is for synchronizing payment result from upstream payment gateway if cp needs the lateast payment result.
* url:{{domain}}/api/v1/payment/syncOrder/:paymentId
* method:POST
* content-type:application/json
* header:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| api-key | string | 64 | true | Npay povide api-key to cp |
* body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| needNotify | number | 1 | true | 0:no need to notify,1:need to notify.**If needNOtify is 1,Npay will do [Notify CP server after user paid again.](#Notify-CP-server-after-user-paid)**|
* response status:200
* response body:
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| actionType | number | 1 | true | Please check with Action Type Definition of Appendix. |
| data | string | no limit | true | "OK" |
### Appendix
**All additionalFields items:**
| Column | Type | Length | IsRequired| Description |
|-------------|---------------------|--------------|-----------|----------------------------|
| email | string | 50 | false | |
| phone | string | 20 | false | |
| name | string | 20 | false | |
| userSignUpTime| string | 10 | false | unix timestamp |
## Payment Status
| Status | Kind | Description |
|-------------|---------------------|-----------------------------------|
| -2 | Payment_failed | user paid failed |
| 0 | Payment_created | create Npay payment |
| 1 | Payment_issued | request payment gateway do tx |
| 2 | Payment_Completed | **user paid successfully** |
## Action Type Definition
| Type | Definition |
|-----------|---------------------|
| 0 | create payment |
| 1 | issue payment to third party payment gateway|
| 2 | notify CP create payment(optional)|
| 3 | notify CP create payment success|
| 4 | notify CP create payment fail|
| 5 | receive callback from third party payment gateway|
| 6 | notify CP payment result|
| 7 | retry notify CP payment result first time|
| 8 | retry notify CP payment result second time|
| 9 | retry notify CP payment result third time|
| 10 | retry notify CP payment result forth time|
| 11 | retry notify CP payment result fifth time|
| 12 | notify CP payment result success|
| 13 | notify CP payment result fail|
| 14 | notify CP payment result manual|
| 15 | notify CP payment result manual success|
| 16 | notify CP payment result manual fail|
| 17 | sync order response|
| 18 | CP get payment|
## Currency Support List
* TWD
* CNY
* USD
* HKD
## PayMethod Category List
* alipay
* wechatpay
* unionpay
* creditcard
* storebarcode
* virtualaccount
* webatm
* test(only in sandbox)
## How to encrypt or decrypt
* Online tool: https://www.devglan.com/online-tools/aes-encryption-decryption
* We use AES 256 CBC encrypt algorithm.
* key(utf-8) length is 32 characters. iv(utf-8) is 16 characters.
* plainText must be a JSON string and the encoding is utf-8.
* cipherText's encoding is base64.
```javascript=
const crypto = require('crypto');
const AESEncrypt = (plainText, key, iv) => {
let cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
return Buffer.concat([
cipher.update(message),
cipher.final()
]).toString('base64')
}
const AESDecrypt = (cipherText, key, iv) => {
let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
return Buffer.concat([
decipher.update(message, 'base64'),
decipher.final()
]).toString()
}
```