hf7777
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Cowpay api 说明 1. 目标读者 本文的主要目标读者是支付平台合作方的技术对接人员 2. 名词定义 * 合作方:指对接支付平台的机构 * 商户:指委托收单的营业机构,如超市,便利店等 # 数据交互与通讯安全协议 > 本章介绍支付平台对接交互模式一级通讯安全协议,描述组成支付平台的各个组件以及他们之间的协作方式,以及在通讯过程中保证数据的保密性和完整性。 ## 1.通讯安全协议 ### 1.1 通讯过程 1. 合作方请求报文上送时,采用HTTP/HTTPS协议,POST推送方式,编码格式统一为UTF-8。 2. 请求报文: >统一请求报文格式: { "signtype": "MD5", "sign": urlencode($sign, 'utf8'), "transdata": urlencode($data, "utf8") } * signtype 为签名算法,默认为MD5算法 * sign 为业务请求签名后数据,并URLEncoder.encode(sign, “UTF-8”) * transdata 为JSON格式的业务请求报文,并URLEncoder.encode(transdata, “UTF-8”) 3. 报文结构及样例: > 所有请求报文统一采用JSON格 { "transdata":"%7B%22pay_type%22%3A%2210072%22%2C%22user_no%22%3A%22Neo%22%2C%22product _name%22%3A%22pidai%22%2C%22product_code%22%3A%22product-123%22%2C%22order_no%22%3A%221507704879000%22%2C%22order_time%22%3A%222017-10-12T12%3A22%3A05.452Z%22%2C%22order_amount%22%3A0.1%2C%22payment%22%3A%22%E6%94%AF%E4%BB%98%E6%88%90%E5%8A%9F%22%7D", "sign":"RLiujUr8AHm7V%2BNfPmdzkZgFuwiluyxJJNkso9nep3YY2wCO4lCh444Nk%2Fr1SxN2CxmpJ333DuaZfNPsBd647Q%2FYpH89fIYz3A07H7NE8EWN008FNBwDhBr6N3hyisJMNdwsJof7D3tCTtc28adOlC5k1naToseOP3x38H%2Fe5Vg%3D", "signtype": "MD5" } ## 2. 签名 >当前签名仅支持MD5方式,待签名字段(transdata是json格式,不用排序)无需排序。以transdata的json内容进行签名:将所有非空字段按ASCII码排序,以 key=value 形式用&(与符号)连接起来,最后拼上&key=${key},进行md5签名,并把签名转大写。先签名后urlencode ### 2.1 2.1 拼装必要参数 { merchant_code: '1001', pay_type: 'india-upi', user_no: '1', notify_url: 'http://www.cowpay.com', return_url: 'http://www.cowpay.com/', product_name: 'ttt001', product_code: 'test001', order_no: '541445444144414', order_time: '20201102081725', order_amount: 11.00, merchant_ip: '127.0.0.1' } 2.2 转成JSON >将对象转成json字符串 2.4 拼装请求报文 { "signtype": "MD5", "sign": urlencode($sign, 'utf8'), "transdata": urlencode($data, "utf8") } 2.5 对transdata和sign进行urlencode 2.6 MD5签名源样例(代收) ```merchant_code=test1111&notify_url=1&order_amount=50.00&order_no=541445444144414&order_time=20201102081725&pay_type=india-upi&product_code=test001&product_name=ttt001&return_url=1&user_no=51070173&key=F1C14F3DEFF6A38450BA97161A3DF3C``` 2.7 MD5签名源串样例(代付) ```bank_branch=KKBK0000888&bank_card=624144124411xxxx&merchant_code=test1111&notify_url=1&order_amount=3&order_no=541445444144414&&pay_type=india-bank-repay&user_name=Michael Taylor&key=F1C14F3DEFF6A38450BA97161A3DF3CF``` ## 3. 请求接口 >POST Application/json 请求接口 ## 4. 测试账号 >测试账号只能调试支付,调试完支付之后,请联系商务下正式号 测试账户请跟商户申请 # 接口参数符号约定 >在接口文档出现的具体报文格式描述中, “出现要求”列包含的值的含义如下表表示: | 符号 | 请求方约束 |服务方约束| | ------ | ------ |------| | M | 必须包含该域 |必须校验该域是否存在和内容的合法性| | C | 如果条件符合必须包含该域 |当条件满足时,必须校验该域是否存在 当该域存在时,必须检查其内容的合法性| | O | 该域可选 |当该域存在时,必须检查其内容的合法性| # 常见错误解决方案 ## 1. 提示不是JSON类型,JSON解析出错 >原因: 1.1 报文格式错误,请查参考章节‘数据交互与通讯安全协议 1.2 头部字段未设置好Content-type:application/json 1.3 传递的不是JSON类型字符串 ## 2. MD5加密提示验签失败 >原因 2.1 输入字段中间带有空格 2.2 Md5加密串是否正确 2.3 signtype的值是否为MD5 2.4 signtype字段拼写错误 3.3 加密串不是transdata 未urlencode前的数据 ## 4. 提示商户号验证失败,请检查商户号和merchant_code是否填写正确 4.1 检查请求的host是否正确 4.2 向商务咨询是否开户 ## 5. 提示交易功能未开通,请联系商务开通 >联系运营人员开户 ## 6. 向商务咨询是否开户 6.1 确认运营人员是否配置好通道 6.2 确认输入金额是否传入限额内的金额或是固定金额指定的金额(如果是固额) ## 7. 提示通道维护中,请联系客服。 7.1 请联系运营开启通道 ## 8. 接口返回 This library (validator.js) validates strings only 8.1 请检查除order_amount字段以外的值是否都为String类型 ## 9. 获取支付地址后,打开无法获取支付页面 9.1 (yl,jd,zhifubao-h5,weixin)类型支付地址需要转成二维码,用相应的app扫码 9.2 咨询运维人员通道是否正常 ## 10. 请先联系商务设置IP白名单 检查merchantcode是否填写正确 ## 11 异步用什么加密方式 异步加密方式看下单(代付/支付)的加密方式,下单如果用MD5异步加来就是MD5,如果是RSA异步加来也是RSA ## 12. 请求方只需要返回Response status code 200即表示确认收到通知 此处不是指返回内容,而是指http状态码(如果完全不知道如何设置,麻烦直接响应一个空请求或者返回字符串200均可,默认情况下请求成功响应码即为200) # 对接说明 * 支付对接文档: * 网关服务器地址:`https://pay365.cowpay.co` * 商户管理后台:`https://m138.cowpay.co` * 支付下单地址:`/pay` * 支付订单查询地址: `/queryPayOrder` * 发起提现: `/v2/withdraw` * 提现订单查询:`/v2/queryWithdrawOrder` * 余额查询:`/v2/queryBalance` * 接口请求中需要的账户信息 商户号(merchant_code)、密钥(MD5)、签名私钥(RSA) 使用后台网址登录,找到个人配置获取 * 回调IP:`平台获取` * 接口地址 = 网关(host) + 接口路由(path 看文档对应接口 请求URL项目) # 1.支付下单接口 >简要描述: * 统一支付下单接口 > 请求URL: • `${host}`/ pay > 请求方式: * POST * application/ json > 参数: | 参数名 | 必选 | 类型 | 最大长度 | 中文描述 | 说明 | | ------ | ------ |------|------|------|------| | merchant_code | M |string|20|商户编号|平台分配的唯一编号| | order_no | M |string|30|商户订单号|平商户订单号,不可重复,最长30位| | order_amount | M |string||交易金额|单位:inr(只支持整数)| | order_time | M |string|15|交易时间|时间戳,纯数字| | product_name | M |string|60|产品名称|请尽量不要传固定值,否则会影响成功率;请尽量不要带空格。| | notify_url | M |string|254|异步通知地址|异步回调通知地址,不支持参数传递| | pay_type | M |string|30|支付类型|指定支付方式,详见 `[支付类型]`| | return_url | C |string|30|成功回跳地址|提交成功后跳转的地址,非必填,但建议商户也传递该字段| | payer_info | C |string|30|付款人姓名|付款人姓名| >返回示例 ``` { "code":0, "content": { "accountName":"Dhanendra prakash singh ", "upi":"Dhanendra973@federal" }, "html":"", "msg":"操作成功", "orderNo":"C1731191630813200384", "payUrl":"https://mm.cowpay.cc/pay125605ef1927312c77995d4ac133696ee0fab741e8baa6ac554","qrcode":"image/gif;base64, /9j/4AAQS" } ``` >返回参数说明 | 参数名 | 类型 | 说明 | | ------ | ------ |------| | code | int |请求结果,0代表成功,其他为失败| | msg | string |失败原因| | html | string |部分通道会以 html 字符串的形式输出,商户优先判断html字段是否存在,在则输出到页面中,页面会自动跳转,否则使用payUrl| | orderNo | string |订单号| | payUrl | string |支付收营台地址链接| | qrcode | string |收款二维码| | content | json |{"accountName":"Dhanendra","upi":"Dhanendra973@gmil.com"}| | accountName | string |upi账号收款人名称| | upi | string |upi账号| # 2.支付订单查询 ## 简要描述: * 统一支付下单接口 ## 请求URL: • `${host}`/queryPayOrder ## 请求方式: * POST * application/ json ## 参数: |参数名|必填|类型|长度|中文描述|说明 |------|------|------|------|------|------ |merchant_code|M|string|商户编号|平台分配的唯一编号 |order_no|M|sting|商户订单号|商户订单号 |signtype|M|sting||签名类型 `MD5` 或 `RSA` |sign|M|sting||生成签名串`A7F0F0EB66562B3AC105F719E5E56960` ## 请求参数 ``` { "sign":"A7F0F0EB66562B3AC105F719E5E56960", "signtype":"MD5","transdata":"%7B%22order_no%22%3A%22I0543064507662789%22%2C%22merchant_code%22%3A%221698133934504%22%7D" } ``` ## 查询成功返回数据 |参数名|类型|说明 | ------ |------|------ |order_no|String|订单号 |merchant_code|String|商户号 |sign|String|验证签名 |pay_type|String|支付类型 |payment|booloean|true:支付成功 false:支付失败 |order_time|long|Timestamp |order_amount|String|订单金额 |status|booloean|true:订单存在 false:订单不存在 ``` { "order_no":"I0543064507662789", "merchant_code":"1698133934504", "order_amount":"500.00", "sign":"0F39BB8C132071B96BBC1737AF0FFBC2", "pay_type":"india-upi-h5", "payment":true, "order_time":1701585044000, "status":true } ``` ## 查询失败返回数据 ``` {"message":"查询不到该笔订单信息","status":false} ``` # 3.支付异步通知 >服务端发送的验签与支付验签相同 支付成功后会将以下字段通过JSON的方式POST到支付时填写参数地址,请求方只需要返回Response status code 200即表示确认收到通知,否则我们会每隔5分钟再次请求你们提交的异步接口,直达请求10次后,就不在发起请求 * POST字段如下: * 异步回调报文示例: ``` 无utr示例: { "transdata":"%7B%22pay_type%22%3A%2210072%22%2C%22user_no%22%3A%22Neo%22%2C%22product_name%22%3A%22pidai%22%2C%22product_code%22%3A%22product-123%22%2C%22order_no%22%3A%221507704879000%22%2C%22order_time%22%3A%222017-10-12T12%3A22%3A05.452Z%22%2C%22order_amount%22%3A0.1%2C%22payment%22%3A%22%E6%94%AF%E4%BB%98%E6%88%90%E5%8A%9F%22%7D", "sign":"RLiujUr8AHm7V%2BNfPmdzkZgFuwiluyxJJNkso9nep3YY2wCO4lCh444Nk%2Fr1SxN2CxmpJ333DuaZfNPsBd647Q%2FYpH89fIYz3A07H7NE8EWN008FNBwDhBr6N3hyisJMNdwsJof7D3tCTtc28adOlC5k1naToseOP3x38H%2Fe5Vg%3D" } 有utr示例: { "sign":"DA7046288CA8199B2ECC1D41D29834AE", "transdata":"%7B%22order_no%22%3A%22I6060301291056389%22%2C%22order_time%22%3A1717655449000%2C%22product_code%22%3A%22%E5%95%86%E5%93%81Code%22%2C%22product_name%22%3A%22%E5%95%86%E5%93%81%E5%90%8D%22%2C%22user_no%22%3A%221%22%2C%22order_amount%22%3A%22100.000%22%2C%22utr_code%22%3A%2211111%22%2C%22pay_type%22%3A%22india-upi-h5%22%2C%22payment%22%3A%22%E6%94%AF%E4%BB%98%E6%88%90%E5%8A%9F%22%7D" } ``` > 验签字段包含在”sign”字段,验签规则与发起支付相同,将transdata urldecode后获取到的JSON数据与私钥一起加密后urlencode。只有支付成功才会通知。请收到通知后校验签名和金额,并做好重复通知的处理。 > `transdata` 字段decode后为JSON字段如下: |参数名|类型|说明 | ------ |------|------ |order_no|String|商户订单号| |order_amount|String|订单金额(卢比为单位) |order_time|String|系统订单创建时间戳(毫秒) |pay_type|String|订单支付通道码 |product_name|String|支付时上传的商品名称 |product_code|String|支付时上传的商品CODE |user_no|String|支付时上传的用户ID |payment|String|支付成功,目前该字段值一定为支付成功四个字 |utr_code|String|交易utr,不为空时才返回,并参与签名;为空时不返回,不参与签名 # 4.代付下单 > 简要描述: * 代付下单接口 * 后台代付需要绑定谷歌验证码,请联系商务 * API代付需要报备IP,请联系商务 ## 请求URL: * `${host}`/v2/withdraw ## 请求方式 * POST * application/json >参数 |参数名|必填|类型|长度|中文描述|说明 |------|------|------|------|------|------ |merchant_code|M|string|20|商户编号|平台分配的唯一编号 |order_no|M|string|30|商户订单号|商户订单号,不可重复 |order_amount|M|string|30|交易金额|单位:inr(100-50000,只支持整数) |pay_type|M|string|100|代付类型|代付类型:`india-bank-repay`或`india-upi-repay` |bank_name|C|string|100|银行名称|银行名称,不限制,随意填,upi代付不用填 |bank_card|M|string|32|银行卡号或upi账号|`e.g: 3339997788`,`xxx@sbi` |bank_branch|OM|string|50|IFSC Code,upi代付不用填|`e.g: KKBK0000888` |user_name|M|string|50|持卡人姓名|`e.g: Michael Taylor` |notify_url|M|string|50|持异步通知地址|`e.g: https://callback.xxxxx/` >返回示例 ``` { "status": true, "message": "代付申请提交成功" } ``` >返回参数说明 |参数名|类型|说明 |------|------|------ |status|boolean|请求结果,true代表代付发起成功,其他为失败 |message|string|失败原因 # 5.代付异步通知 ## 服务端发送的验签与支付验签相同 >支付成功后会将以下字段通过JSON的方式POST到支付时填写参数地址,请求方只需要返回Response status code 200即表示确认收到通知,否则我们会每隔5分钟再次请求你们提交的异步接口,直达请求10次后,就不在发起请求验签字段包含在”sign”字段,验签规则与发起支付相同,将transdata urldecode后获取到的JSON数据与私钥一起加密后urlencode。 * `transdata` 字段decode后为JSON字段如下: |参数名|类型|说明 |------|------|------ |order_no|boolean|商户订单号 |order_amount|string|订单金额(inr为单位) |message|string|返回:提现成功,提现失败 |resp_code|string|以该字段判断代付结果:`S` 代付成功,`F` 代付失败,`P` 代付中 |utr_code|String|该字段有值时才返回,并参与签名;无值时不返回,不参与签名。 # 6.代付订单查询 ## 简要描述 * 代付订单查询 ## 请求URL * `${host}`/v2/queryWithdrawOrder ## 请求方式: * POST * application/json |参数名|必填|类型|长度|中文描述|说明 |------|------|------|------|------|------ |merchant_code|M|string|商户编号|平台分配的唯一编号 |order_no|M|sting|商户订单号|商户订单号 |signtype|M|sting||签名类型 `MD5` 或 `RSA` |sign|M|sting||生成签名串`A7F0F0EB66562B3AC105F719E5E56960` ## 返回参数 |参数名|类型|说明 | ------ |------|------ |order_no|String|订单号 |merchant_code|String|商户号 |sign|String|验证签名 |order_amount|String|代付金额 |message|String|提示消息 |order_time|long|Timestamp |status|booloean|true:订单存在 false:订单不存在 |resp_code|String|S:成功 F:失败 P:代付中 * 支付成功 ``` { "status": true, "merchant_code": "test001", "order_no": "15621201145410", "message": "提现成功", "order_time": "20201223181928", "order_amount": "5.01", "resp_code": "S" } ``` * 订单不存在 ``` { "status": false, "message": "查询不到该笔订单信息"} ``` ## 返回参数说明 |参数名|类型|说明 |------|------|------ |status|Boolean|查询状态:true 代表查询成功 ## status为true时,会返回以下内容: |参数名|类型|说明 |------|------|------ |merchant_code|string|商户编号 |order_no|string|商户订单号 |order_amount|string|订单金额(inr为单位) |order_time|string|系统下单时间 |resp_code|string|查以该字段判断代付状态。`S` 代付成功,`F` 代付失败,`P` 代付中 |message|string|订单状态描述 |sign|string|urlencode后的加密字段。待加密内容为:除sign字段之外的其他字段的json ## status为false时,会返回以下内容: |参数名|类型|说明 |------|------|------ |message|Boolean|查询请求失败时,此字段将会返回具体错误信息 # 7.查询余额 ## 简要描述: * 查询余额 ## 请求URL: * `${host}`/v2/queryBalance ## 请求方式: * POST * application/json ## 参数: |参数名|必填|类型|长度|中文描述|说明 |------|------|------|------|------|------ |merchant_code|M|string|商户编号|平台分配的唯一编号 ## 返回示例 * 成功返回 ``` { "status": true, "balance": {"merchant_code": "test001001", "total_order_amount": 1000.45, "cashing_balance": 1000.23, "total_withdraw_amount": 120.00, "frozen_balance": 10.00, "balance": 154.23, "withdraw_balance": 2541.23, "unsettled_balance": 0, "freeze_balance": 0 } } ``` * • 请求失败 ``` { "status": false, "message": "失败原因"} ``` ## 返回参数说明 |参数名|类型|说明 |------|------|------ |status|Boolean|请求成功与否标志 |message|string|失败原因,status为false返回 |balance|json Object|余额明细,status为true返回 ## balance参数 status为true返回 |参数名|类型|说明 |------|------|------ |merchant_code|string|平台分配的唯一编号 |total_order_amount|Number|交易总金额 |cashing_balance|Number|代付中金额 |total_withdraw_amount|Number|已代付总金额 |frozen_balance|Number|冻结中金额 |balance|Number|总余额 |withdraw_balance|Number|可提现余额 |unsettled_balance|Number|未结算余额 # 支付类型 > 目前支持的支付类型。注:平台当前仅开放 india-upi和india-upi-h5 |支付类型|中文描述 |------|------ |india-upi|upi扫码 |india-upi-h5|upi自动唤醒 |india-bank|印度银行卡代收 # 签名和验签示例:Java代码 ``` package com.xxx; import com.alibaba.fastjson.JSONObject; import lombok.Data; import org.apache.commons.lang3.StringUtils; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.MessageDigest; import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class SignatureDemo { static String md5Key = "xxxxxxxxx"; public static void main(String[] args) throws Exception { //request json string String request = signatureAndRequest(); //verify signature decrypt(request); } private static String signatureAndRequest() throws UnsupportedEncodingException { //pay params Pay pay = new Pay(); pay.setMerchant_code("111"); pay.setPay_type("222"); pay.setUser_no("333"); pay.setNotify_url("444"); pay.setReturn_url("555"); pay.setProduct_name("666"); pay.setProduct_code("777"); pay.setOrder_no("888"); pay.setOrder_time("999"); pay.setOrder_amount("1"); pay.setMerchant_ip("2"); //params order by ascll JSONObject jsonObject = (JSONObject) JSONObject.toJSON(pay); String waitSignStr = mapToStringByASCll(jsonObject) + "&key=" + md5Key; //signature String sign = hash(waitSignStr).toUpperCase(); //request params HashMap<String, String> requestMap = new HashMap<>(); requestMap.put("signtype", "MD5"); requestMap.put("sign", URLEncoder.encode(sign, "UTF-8")); requestMap.put("transdata", URLEncoder.encode(jsonObject.toJSONString(), "UTF-8")); String request = JSONObject.toJSONString(requestMap); return request; } public static void decrypt(String json) throws UnsupportedEncodingException { JSONObject receiveJson = JSONObject.parseObject(json); String transdata = URLDecoder.decode(receiveJson.getString("transdata"), "UTF-8"); String waitSignStr = mapToStringByASCll(JSONObject.parseObject(transdata)) + "&key=" + md5Key; if (hash(waitSignStr).toUpperCase().equals(URLDecoder.decode(receiveJson.getString("sign"), "UTF-8"))) { System.out.println("signature verify success"); } else { System.out.println("signature verify failed"); } } @Data public static class Pay { private String merchant_code; private String pay_type; private String user_no; private String notify_url; private String return_url; private String product_name; private String product_code; private String order_no; private String order_time; private String order_amount; private String merchant_ip; } public static String mapToStringByASCll(JSONObject object) { Map<String, Object> map = (Map<String, Object>) object.toJavaObject(Map.class); String[] sortedKeys = (String[]) map.keySet().toArray((Object[]) new String[0]); Arrays.sort((Object[]) sortedKeys); StringBuilder sb = new StringBuilder(); byte b; int i; String[] arrayOfString1; for (i = (arrayOfString1 = sortedKeys).length, b = 0; b < i;) { String key = arrayOfString1[b]; if (!"sign".equals(key)) { if (map.get(key) != null && !StringUtils.isBlank(map.get(key).toString())) sb.append(key).append("=").append(map.get(key).toString()).append("&"); } b++; } sb.deleteCharAt(sb.length() - 1); return sb.toString(); } private static byte[] md5(String s) { try { MessageDigest algorithm = MessageDigest.getInstance("MD5"); algorithm.reset(); algorithm.update(s.getBytes("UTF-8")); byte[] messageDigest = algorithm.digest(); return messageDigest; } catch (Exception e) { return null; } } private static final String toHex(byte[] hash) { if (hash == null) { return null; } StringBuffer buf = new StringBuffer(hash.length * 2); for (int i = 0; i < hash.length; i++) { if ((hash[i] & 0xFF) < 16) { buf.append("0"); } buf.append(Long.toString((hash[i] & 0xFF), 16)); } return buf.toString(); } public static String hash(String s) { try { return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8"); } catch (Exception e) { return s; } } } ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully