# Introduction

This document provides an overview of Pyvio API, through which you may easily collect funds from online platforms B2B buyers, or deposit funds to your Pyvio global collection virtual accounts in local currencies. You can also withdraw funds to your beneficiary account, or initiate payments to your third-party suppliers.

# SDK Download

Java SDK (opens new window)

PHP SDK (opens new window)

# APP Access Process

# Get App ID and App Secret

Please contact Pyvio Dev Team to get your unique app_id and app_secret for making calls to the API.

Note:

The app_id is the unique identification of the web app.

The app_secret is the key of the web app.

Pyvio Public Key is for notification validation.

# Public Key

Public key is used to verify the API requests. Please contact Pyvio Dev Team to provide your public key information.

# IP WhiteList

Please contact Pyvio Dev Team to provide the IP address for whitelist. To help your integration operate securely, we must verify that it’s communicating through one of our listed IP addresses.

If your integration also receives webhooks from us, make sure these events originate from a whitelisted IP address.

# API Call Description

# Host

  1. Sandbox: https://sandbox-api.pyvio.com

  2. Production: https://api.pyvio.com

# Http Method

GET/POST

# Common Header

HEADER PARAMETERS
Request-Id
required
string(32)
As long as it is unique among the requests within the past 7 days.Duplicated request cannot be processed.
Authorization
conditional
text
JWT access token.
Sign
conditional
text
RSA Sign,All Post requests is be required.
X-Timestamp
conditional
long(ms)
Timestamp,it`s used for signature verification, and it is required for POST requests.
Content-Type
conditional
enum
Required for POST requests.
One Of
application/json
X-Unit-Id
conditional
string(32)
All sub-merchants are required.

# Sign

Signature is the verification of the body of the messages during the interaction between the Pyvio and the merchant. Signature usually occurs in post http request. There is also a webhook message used by Pyvio to notify merchants of data changes.

Pyvio uses the RSA private key to decrypt, and the RSA public key to sign.Therefore, during the API interaction, there are merchant RSA public and private keys and Pyvio RSA public and private keys.

The signing rules are as follows:

  1. The merchant sends a request to Pyvio, the merchant uses its own RSA private key to sign, and Pyvio uses the merchant's RSA public key to verify the signature;
  2. Pyvio sends a notification to the merchant, Pyvio uses its own RSA private key to sign, and the merchant uses the Pyvio RSA public key to verify the signature;
  3. Signing is to encrypt the http request body, app_id,timestamp,For specific rules, see the following signature example;
  4. Whether it is the public and private keys of the merchant or the platform, the generation method is to use the PKCS8 padding method and 2048 length Tool (opens new window);
  5. sign out and base64 as the signed string;
  6. Put the encrypted string in the header Sign.

# Sample code

    package com.pyvio.developer.sdk.aop;
    
    import org.apache.commons.codec.binary.Base64;
    
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    public class SignTest {
    
        /**
         * 参数签名(${appId}${timestamp}${requestBody})
         * @param content
         * @param privateKey
         * @return
         * @throws Exception
         */
        public static String sign(String content,String privateKey) throws Exception {
            Signature signature = Signature.getInstance("SHA256WithRSA");
            PrivateKey prk = getPrivateKeyFromPKCS8("RSA",privateKey);
            signature.initSign(prk);
            byte[] bytes = content.getBytes("UTF-8");
            signature.update(bytes);
            byte[] signed = signature.sign();
            return Base64.encodeBase64String(signed);
        }
    
        public static boolean signCheck(String content,String sign, String publicKey) {
            try {
                PublicKey pubKey = getPublicKeyFromX509("RSA", publicKey);
                java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
                signature.initVerify(pubKey);
                signature.update(content.getBytes("UTF-8"));
                return signature.verify(Base64.decodeBase64(sign.getBytes()));
            } catch (Exception e) {
                return false;
            }
        }
    
        private static PrivateKey getPrivateKeyFromPKCS8(String algorithm, String privateKey) throws Exception {
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            byte[] encodedKey = privateKey.getBytes();
            encodedKey = Base64.decodeBase64(encodedKey);
            return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
        }
    
        private static PublicKey getPublicKeyFromX509(String algorithm, String publicKey) throws Exception {
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            byte[] encodedKey = publicKey.getBytes();
            encodedKey = Base64.decodeBase64(encodedKey);
            return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
        }
    
        public static void main(String[] args) throws Exception {
            //partner app id
            String appId = "1569641270953589504";
            //request time
            Long timestamp = 1666332361000L;
            //partner rsa private key
            String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALxGyg3/boLT2I8dQnC3Njc2XIDJgZM/G4wqsDDUVoy/PQ2THA39sKHiLsTg71zVbQZ4+UYWm1aTlms7KuBuOmvmdIzKuI04NbSuDeAbAtnraizhELSOpVQFNom2tIGHw4/46VuF3bE0rgFjKGqrRI9xOVEcDGZlP4h9JatQEgytAgMBAAECgYADZ1dX9Awy+A+NlAFm4BQrcXFy1xt7GIGUHaSUCe3N7sxY45uB+F+vyVh6aJm74QlCaJvmQv62Lg5t1HOQ2pcHD6/r7G0lykjYJ3JEAmF3KKm/FgPqX9MGqZCBNHp3oQaHMf8WwRfjxr/EBT1QfdItCGjiENJ4bjSJo9qzEPtjSQJBAMx/r6clsTUdpeskw60UMJG17Af5Fc/SNCsq8hdmCqva0QtT1l/vprmwEH1hKXlA9au9cIESp0ceABH86jE9Vu8CQQDrsTt/S6iiWAiJKA8eYWSEcPyQXoB+tveg4ZoKUwG+fT5t9tXOuPZGmC7CWsAATfO88/ySGqNyIlFgSDvTM3YjAkB+c9JdLCyI6L1pSwGIq/xgjbrXL0oyiQvjSZoLp/ifTh6Hv57HEfzpw5pevU8VAHspaGoCFlPD4SQv+1GhgwmXAkAd6grBJ1sp7751mg4BLx9Q5/5GXJg2fQaE9t1UPiDUipTn5BJTAIrRfvNAW8BOyZYL/3OpH5RrIgvuCnz9W2S9AkB19MQtKSc3Ba36Jo3C0kvTdeSDBR4o+ah+bzhwg/Hj8EKYp4IoyW8mx32WXtSLGp8OjupPlZ65PUkzy838Eo8v";
            //partner rsa public key
            String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8RsoN/26C09iPHUJwtzY3NlyAyYGTPxuMKrAw1FaMvz0NkxwN/bCh4i7E4O9c1W0GePlGFptWk5ZrOyrgbjpr5nSMyriNODW0rg3gGwLZ62os4RC0jqVUBTaJtrSBh8OP+Olbhd2xNK4BYyhqq0SPcTlRHAxmZT+IfSWrUBIMrQIDAQAB";
            // post request json body,read from request stream
            String requestBody = "{\"grant_type\":\"client_credentials\",\"app_id\":\"1569641270953589505\",\"app_secret\":\"bc2ead7739f447c49032b4aef7818c47\"}";
    
            //generate rule
            String signContent = appId + timestamp + requestBody;
            String sign = sign(signContent,privateKey);
            System.out.println(sign);
            System.out.println(signCheck(signContent,sign,publicKey));
        }
    }
    
    
    // Make sure to add code blocks to your code group

    # Errors

    If a request fails, we will respond with error details. If the response is not received, it may mean that the network has timed out, and please try again.

    Response code Description
    B_XXXX Bad request - The request is invalid due to missing parameters, an incorrect structure, or failure in another validation test.
    S_XXXX The request has been interrupted, possibly due to an unknown exception or triggering some of our business rules. Please reach out to the Pyvio Dev Team for assistance.

    # Error Codes

    Response code Description
    S_Common_SystemError The request may have encountered an unknown exception, leading to a disruption in the process. Please contact the Pyvio Dev Team for assistance.
    B_Common_AuthError Unauthorized - Please ensure that a valid authentication token is provided.
    B_Auth_TokenInvalidError Unauthorized - Please get a new authentication token.
    B_Common_NotFound Not found - The requested endpoint does not exist.
    B_Common_ParamError An incorrect type or failed validation test occurred with a provided argument.

    # Failed Example Response

    {
      "code": "S_Common_DivError",
      "message": "The provided app_id is invalid."
    }
    

    # Success Example Response

    {
      "code": "SUCCESS",
      "message": null,
      "data": {}
    }