VM_API
简体中文
  • 简体中文
  • English
    VM_API
    简体中文
    • 简体中文
    • English
    • 接入指南
    • 环境配置
    • 全局错误码
    • 储值卡
      • 申请卡
        POST
      • 卡详情
        POST
      • 冻结/解冻卡
        POST
      • 删卡
        POST
      • 卡充值
        POST
      • 卡退款
        POST
      • 交易记录
        POST
      • 获取卡产品码
        POST
      • 获取账户余额
        POST
    • 通知
      • WebHook
    • 获取accessToken
      GET

    接入指南

    概述#

    请使用具有 API 管理权限的用户账户登录 VM 控制台,在 个人中心 -> 开发者 标签页进行 Webhook 配置与 API 账户创建,API 账户创建成功后,可以使用 API Key 来访问 VM API 。
    注意事项
    1.
    API只能管理通过API创建的card!!!

    认证#

    accessToken用于对用户进行身份验证,并允许访问API上的操作。所有API都使用accessToken作为认证客户端请求的机制。您的访问令牌应始终保密和安全。
    请求时,需要先获取accessToken,并在请求头Authorization 添加上获取到的accessToken

    生成公私钥#

    您可以使用 OpenSSL 生成 RSA 私钥(api_private.pem 为您的 API RSA 私钥 ):
    openssl genpkey -out api_private.pem -algorithm RSA -pkeyopt rsa_keygen_bits:4096
    使用 OpenSSL 生成 RSA 私钥对应的公钥(api_public.pem 为您的 API RSA 公钥):
    openssl rsa -in api_private.pem -out api_public.pem -pubout
    保存商户公钥例子 需要把头部和尾部都保存进来
    -----BEGIN PUBLIC KEY-----
    MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6v8JgHmwJS1gK1IR9jpb
    fHD+mEEwAteV13pmM94ribQELnhbQegvmH/aCDg7nkIZasyQ5H3mfNa1Fuv6IATY
    9Of58gA9TEUkcxzV0JrT0zVpkxmCaejUVA63gi6AVqQZWn4YqRBAqzVzgq4CpOG+
    dGTXy/GS62+EdDvF3jrhPcECAwEAAQ==
    -----END PUBLIC KEY-----

    RSA 加密和解密在接口交互中的对接文档#

    一、请求加密过程#

    1.
    在进行接口请求时,需要将接口请求参数进行加密处理。
    2.
    首先,使用 RSA 算法对请求参数进行加密。假设请求参数是一个字典结构,如body = {'param1': 'value1', 'param2': 'value2'}。
    3.
    调用加密函数encrypt_data_with_public_key(body, public_key_str),其中public_key_str是已知的vm平台公钥字符串。encrypt_data_with_public_key函数见下方示例.
    4.
    加密后得到字符串content。
    5.
    最后,将包含加密内容的字典{'content': content}发送给对应接口。

    二、响应解密过程#

    1.
    接口响应数据为{'code': 0, 'msg':'ok', 'data': '加密数据'}。
    2.
    从响应数据中获取加密的data字段内容。
    3.
    使用 RSA 解密算法对data进行解密,调用解密函数decrypt_data_with_private_key(encrypted_data, private_key_str),其中encrypted_data是响应中的加密数据data,private_key_str是用户已知的私钥字符串。decrypt_data_with_private_key函数见下方示例。(其中填充方式使用PKCS#1 v1.5 填充)
    4.
    解密后得到结构定义的结构体 JSON 串。
    5.
    对解密后的 JSON 串进行 JSON 解码,得到最终可处理的数据结构。

    三、加密和解密函数说明#

    (一)加密函数#

    函数名称:encrypt_data_with_public_key
    功能描述:使用给定的公钥字符串对数据进行加密。
    输入参数:
    data:需要加密的数据,应为可序列化的对象,通常为字典等。
    public_key_str:公钥字符串。
    处理流程:
    加载公钥:使用RSA.import_key方法加载传入的公钥字符串。
    数据转换:将输入数据转换为 JSON 字符串。
    加密数据:使用PKCS1_v1_5加密器对 JSON 字符串编码后的字节数据进行加密。
    Base64 编码:对加密后的数据进行 Base64 编码。
    十六进制编码:对 Base64 编码后的数据进行十六进制编码,并返回结果。

    (二)解密函数#

    函数名称:decrypt_data_with_private_key
    功能描述:使用给定的私钥字符串对加密数据进行解密。
    输入参数:
    encrypted_data:经过加密和编码后的十六进制字符串数据。
    private_key_str:私钥字符串。
    处理流程:
    十六进制解码:对输入的十六进制字符串数据进行解码。
    Base64 解码:对十六进制解码后的数据进行 Base64 解码。
    加载私钥:使用RSA.import_key方法加载传入的私钥字符串。
    解密数据:使用PKCS1_v1_5解密器对 Base64 解码后的数据进行解密。
    数据转换:尝试将解密后的字节数据转换为 JSON 字符串,然后解析为字典并返回。如果转换或解析过程中出现错误,返回None。
    注意事项
    1.
    部分语言可能在解密中会出现需解密的部分过长的问题,这是时候需要将密文进行分段解密。api在加密的时候使用的是[PKCS#1 v1.5]的填充方式,在分段的时候注意分段的填充方式是否一致。

    四、使用示例#

    以下是一个简单的使用示例,展示了接口请求加密和响应解密的过程:
    在实际使用时,需要将your_public_key和your_private_key替换为实际的公钥和私钥字符串。同时,确保数据的格式符合预期,并且在加密和解密过程中没有出现错误。
    注意事项:
    1.
    确保公钥和私钥的正确性和匹配性。
    2.
    加密和解密过程中的数据格式转换可能会因为输入数据的不同而产生错误,需要进行适当的错误处理。
    ##IP 白名单
    在调用 VM API 时,只允许从您设置的 IP 白名单地址发起请求,您需要在创建 API Key 时设置调用发起的 IP 地址,修改后会在10分钟之后生效。

    请求示例#

    请求 base URL#

    https://sandbox-api.vmcardio.com/

    加密前请求参数#

    加密前业务请求参数示例
    {   
    	"apiKey": "341916e58af445f8aadeb95*******",
    	"timestamp": "1623038312088",   
    	"rsaType": "ECB_OAEP",   
    	"aesType": "GCM_NOPADDING",   
    	"bizContent": {     
    		"page": 1,     
    		"pageSize": 1   
    	} 
     }
    

    加密后请求参数#

    	    {
          "apiKey": "341916e58af445f8aadeb95170******",
          "timestamp": "1628652100447",
          "bizContent": "qjFMZXs2n+CxnrNGoaZmGrKQzPosy6QbWEumCMkGOEw=",
          "key": "gYZvuXdJADuaLYMU3z8q5vOtld62PSaPxrrhhr4UGwWbZm7Pw3/VImzHrd3oNy1XT8R55V7pbpQOBVdbmTev/rESnuaXlGofkB04JWAaRCIPytEKMHUNXZXEU9GLVppYst7bgiekMDIDScS4AkD75eDG8zru5Gr+gTxU4AYyHSzB0deQnxmNRemwZn+jaNgNs7WeBcuQWR1Cq2+1At8FlAqF5XzEaeQ3x1Q0N3iaLzSiXHQRYqP1Q6V6/aiIXchin/X9bBRYL618utjm4k0qoXU8Rw2JeEKzn7m2ShyyQQ31zX/rQ1xf0ar5PDtJPU/qYp9Kr4oVtcN6yHdG802nLqpGYlHlMvxy9vpnGFXb9oxh4xYnp0qRUfKLyJIylc3qhq6spHyWnuC5XV1S4lH+rIPNF1icV08ex7pjps2jvTICBzIIPExBamh1n00RcxZbkGqxYfRZ7SLTUCH06EaV5lP8yXNe3fNWjHk4mppaVDj0QFagqTzBM9AwMfHs1dOeDmcwkTacKQsvNRu3l5uZFQYkaUeVB9m3AhKw3lyl2oJIfJgYeBLJEHMGFVZXP92z8+J5KrZEVfkL8F80XkB3sXRP0BiIv/9Mm4VrjopYoDWyXttCysY0lJ9XImRyE7GkSy2sjmW0BCsrECoVHWh73s9o7Kw0uIegFaitch24GsM=",
          "sig": "ZPQcL1aIxMrA6HTq7RWWS8FZS08zSOkS69WohcBw1bDr4Qv2Wkrp2t+PNHMh3TmDUnOmUOiv7mBs/sOw08rhgPHqAU/qtvc1lzJFFOnPp5MBmDgffD1auwm7icGzm3myhEz3hKePxyRgZWB1DpPmMYaRuWt1RYcVmcqRa/Bfd0jR37a35neuOSlaip4jsQE1pHQzQ6itdQhBtZZABl1Plz5u8OaMIDTVj63485zi/n6iuuav+GL+JX2JL6pnWz3CT/9DNqa/McyYbxGswGMBAPgHCptseELVmOQ3ZKNHgMu6EtXEKLzmLeZ5REwnw2MTvpzuy5B1zIuxiafuAhh6Tg==",
          "rsaType": "ECB_OAEP",
          "aesType": "GCM_NOPADDING"
        }
    下一页
    环境配置
    Built with