草庐IT

平台H5对接支付宝支付接口(含分布式源码)

晚风时亦鹿 2023-07-21 原文

简介
本文详细介绍通过支付宝开放平台开发助手生成密钥对、支付宝证书申请 CSR 文件步骤。
说明:生成密钥、CSR 文件后,开发者需根据 生成并配置密钥 指引,完成控制台及接口调用配置。
前提条件
• 已完成开发者入驻以及实名认证。详情可查看 支付宝个人账号注册及实名认证、支付宝企业账号注册及实名认证。
• 已下载并安装下载密钥生成工具(支付宝开放平台开发助手)。
获取工具
• WINDOWS(Windows 版本工具请不要安装在含有空格的目录路径下,否则会导致公私钥乱码的问题)。
• MAC_OSX
原理介绍
支付宝开放平台开发助手提供了一键生成密钥功能,便于开发者生成一对 RSA 密钥(应用公钥、应用私钥)以及公钥证书申请 CSR 文件(在线申请应用公钥证书需要)。
注意事项
• 应用公钥(public key)需提供给支付宝账号管理者上传到支付宝开放平台。
• 应用私钥(private key)由开发者自己保存,需填写到代码中供签名时使用。
• 生成的私钥需妥善保管,避免遗失,不要泄露。
• 密钥和应用(APPID)一一对应,即开发者需要为名下的每个应用分别设置密钥,且不同应用的密钥不能混用。
公钥方式
本步骤指引以 MAC_OSX 界面为例。

  1. 根据开发语言选择密钥格式和密钥长度。
    说明:
    • 新建应用请务必使用 RSA2 密钥长度 即 2048 位。详情可查看 开放平台证书升级指南。
    • 目前已使用 RSA 密钥长度即 1024 位密钥长度的应用仍然可以正常调用接口。

    点击 生成密钥,工具会自动生成商家应用公钥(public_key)和应用私钥(private_key)。随后点击 打开密钥文件路径。

    在弹出的 RSA密钥 文件夹下即可找到生成的公私钥文件。
    根据 生成并配置密钥 指引完成密钥配置。

公钥证书方式
本步骤指引以 MAC_OSX 界面为例。
2. 在开发助手工具的生成密钥工具,密钥长度选择 RSA2,密钥格式选择 PKCS8(Java适用),点击 获取CSR文件 后的 点击获取,生成应用公钥证书 CSR 申请文件。

  1. 在弹出的获取 CSR 对话框中根据提示填写相关信息,支付宝会根据提供的信息创建证书的标识名称,用来识别证书,点击 生成 CSR 文件。
    说明:
    • 组织/公司:名称一定要和开发者中心门户账号信息的公司名称保持一致,否则会导致后续步骤中上传 CSR 证书文件校验失败。
    • 沙箱环境下配置 CSR 公钥证书时,若沙箱账号为:
    • 2020 年 07 月 24 日前获取的沙箱账号,组织/公司 需固定填写 沙箱环境。
    • 2020 年 07 月 24 日后获取的沙箱账号,组织/公司 需填写沙箱商家账号,例如:沙箱商家账号为 xxx@sandbox.com,组织/公司就需要配置成 xxx@sandbox.com。
    • 域名 建议填写商家/服务商公司域名地址。

    在生成 CSR 文件后,点击 打开文件位置,在对应的文件夹里可以看到三个文件:应用公钥 key 串、应用私钥 key 串,以及 .csr 格式的应用公钥证书申请文件。

    根据 生成并配置密钥 指引完成密钥配置

alipay.trade.close(统一收单交易关闭接口)

请求示例

AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
JSONObject bizContent = new JSONObject();
bizContent.put("trade_no", "2013112611001004680073956707");
request.setBizContent(bizContent.toString());
AlipayTradeCloseResponse response = alipayClient.execute(request);
if(response.isSuccess()){
System.out.println("调用成功");
} else {
System.out.println("调用失败");
}

响应示例

{
    "alipay_trade_close_response": {
        "code": "10000",
        "msg": "Success",
        "trade_no": "2013112111001004500000675971",
        "out_trade_no": "YX_001"
    },
    "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
}

xml配置

<alipay_trade_close_response> 
  <code>10000</code>  
  <msg>Success</msg>  
  <trade_no>2013112111001004500000675971</trade_no>  
  <out_trade_no>YX_001</out_trade_no> 
</alipay_trade_close_response>

跳转支付宝链接
https://www.merchant.com/receive_notify.htm?notify_type=trade_status_sync&notify_id=91722adff935e8cfa58b3aabf4dead6ibe&notify_time=2017-02-16 21:46:15&sign_type=RSA2&sign=WcO+t3D8Kg71dTlKwN7r9PzUOXeaBJwp8/FOuSxcuSkXsoVYxBpsAidprySCjHCjmaglNcjoKJQLJ28/Asl93joTW39FX6i07lXhnbPknezAlwmvPdnQuI01HZsZF9V1i6ggZjBiAd5lG8bZtTxZOJ87ub2i9GuJ3Nr/NUc9VeY=&trade_no=null&app_id=null&out_trade_no=null&out_biz_no=null&buyer_logon_id=null&seller_id=null&seller_email=null&trade_status=null&total_amount=null&refund_fee=null&subject=null&body=null&gmt_create=null&gmt_payment=null&gmt_refund=null&gmt_close=null&fund_bill_list=null&receipt_amount=null&invoice_amount=null&buyer_pay_amount=null&point_amount=null&buyer_id=null

统一收单线下交易查询

package com.java.sdk.demo;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.AlipayConfig;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.FileItem;
import java.util.Base64;
import java.util.ArrayList;
import java.util.List;

public class AlipayTradeQuery {

    public static void main(String[] args) throws AlipayApiException {
        String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCSmzXtQZafZ2rA/jI2vP+ww+BWQeMsvIYWntiaCcxsOCS/fRI6BwfcKatwPTrr5Dz39w8rDJymglPi/9VxpXylBLyXEL9G4z2+Dq5J4EY89oDlbyW1ocggE/owFNvbPwnkpn1hCXGxvwYG4iz7sOn8TeR3n+1UJH1o4p7xutq2jAsF5HmfGJQpB51WKX4DNn0vIkSeFZj3DfcQ57UlieWfCexmwf5yR590LtMbE+y7EDCCTtB/ZnAUYs0/C5kXI0HlD5+st5x1bV+33RqJzd29DN5zp/Og+KDYSLvqS2tz3XytUew4cPaqkaWgjSko9zCyuaYcTJrjM0VeqysxygT3AgMBAAECggEAC9lxrWB8vRuNvFWPV29FN1NNoYsnwmjmaZOjLCgYlrKe/b8tJvWEhB32FldMmN5UszILzs3xJ2AnSZSl+s6GWYwddhRLcX5ScjcbjSsMYkcGOgUWxixyUW1r7lDxSDI7KXjvb1VlFBm9cfb77cfp0ZO2IJkThJaCcGTItf8FSHW/Lm6dmbo+HXnGyqhN9rPjAwzk4ieo1PsN1oyNJ1knOfWkIbQXFzYjQXZtBtiePMlbNuBAzAAx2cJ8lI6F+42wEvmYD2g4YEEFLwgoML+jMUCKHykO1uFVfK0WoxMOOLxU4OXxLRWbKyGtc+bzTONfKfJK6VRVJWYjnOCMzB2iaQKBgQDwT27J+WDZNbZRzvIQ9ZhlTTpVY7d1E+rN6CWI9Cq3ApyL+9H/Sfus/jJP8IswEvSGxBT6zrhvRK7Fi0XY7f9I377ULcTKveWnWW9Eu0DbMfvVT8XXitkjf8wl+6EqL+L8OwffeQxJbpqQqnOPyPoOgwcotEjsjFbrXONpPiQVJQKBgQCcLZniFiOb1wzZEEYKK9SfWjO3yr/QcKagBR76qQUqTeYM41z9Naw+paeGofkM0Llo375q6yiSxJI7RHcXxyUN0ZIuw5xeYWNnXdUnASjsRM8MWCqzQ2YtdPkdcIpkRBjGRWZqXC8RPXiHFkSN1QJ+3c4wfALJwUSY4exoLBNs6wKBgEvWJXZj1qZ1huXmUwn7F27QoloUL+8oq+7zFfVUaK58in66p5jS9jOvvJzxols3gCePdbd4yUeD+0uoGhDNesS6p3Q6RWJd7z2SwcSE+4CxE3JLzHmq/b9wMzLBaCjyF8XVszRY9QGvf+OrhvCXUiKGQxobWvAbkcqQ88tgqu5pAoGASttAirD52FQ3AENgjrd7bfWaHFm9nnagJsrNkm843pH/1eWUSHlVWaGkrk8sRAw3EiFL74tPIym8vVOPkYIOLJVqb6eqZ0JelsjOxac0qipA4zXPIaUIcHlEfevXKT/KcB4LfKc6mBTSlE0EBsc2LwC5N1v5KiLMckq3OScHGIkCgYANfP5cGyKySkn2BzTlILnWu+uPHuqaAIV6Fc+Z6h/WbdXw2opdEP3A7GEUQUY6fjYj6AD8Jutn3sz1yd7l5ly+TX6I6YFJ5xHcFcxvl9m/kZIbps+wUjn5mJYZaGcnm2ZYvUD+I0VERLX2yBWg0SWXGuY/Z3mwe4D8nJxZNC4o4g==";
        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjedhtEgisXmKUQ9B+P+IldGYB6Qmo8eZi5cZdJzXPDlDMwofCwQqr8+XTjbhhAWMkMdWbR+pewVjAjcelF0apeRyAJlf9rLi0fADc9XdK32fjPXyUKRRyUX5obguTNaC7w3DoQm5MYnxxaWStFisXkyrIKM3E5ibN0ansdCC8+zF5XfdOffEl/5ohgTM79l1e4LRM/O3ei52fs2Ip03coUrnfeWCvzActeLby+z1rFW9BY3u/DkcSlwAOl3XPIg1r9yulXSDm8W49TDvLgnMIEXyVoOgmjckyOl7vKWti9fiDJ+RnARve01EjIpZx5NNM1MuDx/4OkIiNydgTXJZ1wIDAQAB";
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipaydev.com/gateway.do");
        alipayConfig.setAppId("2021000121663960");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF8");
        alipayConfig.setSignType("RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        request.setBizModel(model);
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }
}

统一交易退款接口

package com.java.sdk.demo;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.AlipayConfig;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.FileItem;
import java.util.Base64;
import java.util.ArrayList;
import java.util.List;

public class AlipayTradeRefund {

    public static void main(String[] args) throws AlipayApiException {
        String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCSmzXtQZafZ2rA/jI2vP+ww+BWQeMsvIYWntiaCcxsOCS/fRI6BwfcKatwPTrr5Dz39w8rDJymglPi/9VxpXylBLyXEL9G4z2+Dq5J4EY89oDlbyW1ocggE/owFNvbPwnkpn1hCXGxvwYG4iz7sOn8TeR3n+1UJH1o4p7xutq2jAsF5HmfGJQpB51WKX4DNn0vIkSeFZj3DfcQ57UlieWfCexmwf5yR590LtMbE+y7EDCCTtB/ZnAUYs0/C5kXI0HlD5+st5x1bV+33RqJzd29DN5zp/Og+KDYSLvqS2tz3XytUew4cPaqkaWgjSko9zCyuaYcTJrjM0VeqysxygT3AgMBAAECggEAC9lxrWB8vRuNvFWPV29FN1NNoYsnwmjmaZOjLCgYlrKe/b8tJvWEhB32FldMmN5UszILzs3xJ2AnSZSl+s6GWYwddhRLcX5ScjcbjSsMYkcGOgUWxixyUW1r7lDxSDI7KXjvb1VlFBm9cfb77cfp0ZO2IJkThJaCcGTItf8FSHW/Lm6dmbo+HXnGyqhN9rPjAwzk4ieo1PsN1oyNJ1knOfWkIbQXFzYjQXZtBtiePMlbNuBAzAAx2cJ8lI6F+42wEvmYD2g4YEEFLwgoML+jMUCKHykO1uFVfK0WoxMOOLxU4OXxLRWbKyGtc+bzTONfKfJK6VRVJWYjnOCMzB2iaQKBgQDwT27J+WDZNbZRzvIQ9ZhlTTpVY7d1E+rN6CWI9Cq3ApyL+9H/Sfus/jJP8IswEvSGxBT6zrhvRK7Fi0XY7f9I377ULcTKveWnWW9Eu0DbMfvVT8XXitkjf8wl+6EqL+L8OwffeQxJbpqQqnOPyPoOgwcotEjsjFbrXONpPiQVJQKBgQCcLZniFiOb1wzZEEYKK9SfWjO3yr/QcKagBR76qQUqTeYM41z9Naw+paeGofkM0Llo375q6yiSxJI7RHcXxyUN0ZIuw5xeYWNnXdUnASjsRM8MWCqzQ2YtdPkdcIpkRBjGRWZqXC8RPXiHFkSN1QJ+3c4wfALJwUSY4exoLBNs6wKBgEvWJXZj1qZ1huXmUwn7F27QoloUL+8oq+7zFfVUaK58in66p5jS9jOvvJzxols3gCePdbd4yUeD+0uoGhDNesS6p3Q6RWJd7z2SwcSE+4CxE3JLzHmq/b9wMzLBaCjyF8XVszRY9QGvf+OrhvCXUiKGQxobWvAbkcqQ88tgqu5pAoGASttAirD52FQ3AENgjrd7bfWaHFm9nnagJsrNkm843pH/1eWUSHlVWaGkrk8sRAw3EiFL74tPIym8vVOPkYIOLJVqb6eqZ0JelsjOxac0qipA4zXPIaUIcHlEfevXKT/KcB4LfKc6mBTSlE0EBsc2LwC5N1v5KiLMckq3OScHGIkCgYANfP5cGyKySkn2BzTlILnWu+uPHuqaAIV6Fc+Z6h/WbdXw2opdEP3A7GEUQUY6fjYj6AD8Jutn3sz1yd7l5ly+TX6I6YFJ5xHcFcxvl9m/kZIbps+wUjn5mJYZaGcnm2ZYvUD+I0VERLX2yBWg0SWXGuY/Z3mwe4D8nJxZNC4o4g==";
        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjedhtEgisXmKUQ9B+P+IldGYB6Qmo8eZi5cZdJzXPDlDMwofCwQqr8+XTjbhhAWMkMdWbR+pewVjAjcelF0apeRyAJlf9rLi0fADc9XdK32fjPXyUKRRyUX5obguTNaC7w3DoQm5MYnxxaWStFisXkyrIKM3E5ibN0ansdCC8+zF5XfdOffEl/5ohgTM79l1e4LRM/O3ei52fs2Ip03coUrnfeWCvzActeLby+z1rFW9BY3u/DkcSlwAOl3XPIg1r9yulXSDm8W49TDvLgnMIEXyVoOgmjckyOl7vKWti9fiDJ+RnARve01EjIpZx5NNM1MuDx/4OkIiNydgTXJZ1wIDAQAB";
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipaydev.com/gateway.do");
        alipayConfig.setAppId("2021000121663960");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF8");
        alipayConfig.setSignType("RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setRefundAmount("200.12");
        request.setBizModel(model);
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }
}

查询对账单下载地址

package com.java.sdk.demo;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.AlipayConfig;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel;
import com.alipay.api.FileItem;
import java.util.Base64;
import java.util.ArrayList;
import java.util.List;

public class AlipayDataDataserviceBillDownloadurlQuery {

    public static void main(String[] args) throws AlipayApiException {
        String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCSmzXtQZafZ2rA/jI2vP+ww+BWQeMsvIYWntiaCcxsOCS/fRI6BwfcKatwPTrr5Dz39w8rDJymglPi/9VxpXylBLyXEL9G4z2+Dq5J4EY89oDlbyW1ocggE/owFNvbPwnkpn1hCXGxvwYG4iz7sOn8TeR3n+1UJH1o4p7xutq2jAsF5HmfGJQpB51WKX4DNn0vIkSeFZj3DfcQ57UlieWfCexmwf5yR590LtMbE+y7EDCCTtB/ZnAUYs0/C5kXI0HlD5+st5x1bV+33RqJzd29DN5zp/Og+KDYSLvqS2tz3XytUew4cPaqkaWgjSko9zCyuaYcTJrjM0VeqysxygT3AgMBAAECggEAC9lxrWB8vRuNvFWPV29FN1NNoYsnwmjmaZOjLCgYlrKe/b8tJvWEhB32FldMmN5UszILzs3xJ2AnSZSl+s6GWYwddhRLcX5ScjcbjSsMYkcGOgUWxixyUW1r7lDxSDI7KXjvb1VlFBm9cfb77cfp0ZO2IJkThJaCcGTItf8FSHW/Lm6dmbo+HXnGyqhN9rPjAwzk4ieo1PsN1oyNJ1knOfWkIbQXFzYjQXZtBtiePMlbNuBAzAAx2cJ8lI6F+42wEvmYD2g4YEEFLwgoML+jMUCKHykO1uFVfK0WoxMOOLxU4OXxLRWbKyGtc+bzTONfKfJK6VRVJWYjnOCMzB2iaQKBgQDwT27J+WDZNbZRzvIQ9ZhlTTpVY7d1E+rN6CWI9Cq3ApyL+9H/Sfus/jJP8IswEvSGxBT6zrhvRK7Fi0XY7f9I377ULcTKveWnWW9Eu0DbMfvVT8XXitkjf8wl+6EqL+L8OwffeQxJbpqQqnOPyPoOgwcotEjsjFbrXONpPiQVJQKBgQCcLZniFiOb1wzZEEYKK9SfWjO3yr/QcKagBR76qQUqTeYM41z9Naw+paeGofkM0Llo375q6yiSxJI7RHcXxyUN0ZIuw5xeYWNnXdUnASjsRM8MWCqzQ2YtdPkdcIpkRBjGRWZqXC8RPXiHFkSN1QJ+3c4wfALJwUSY4exoLBNs6wKBgEvWJXZj1qZ1huXmUwn7F27QoloUL+8oq+7zFfVUaK58in66p5jS9jOvvJzxols3gCePdbd4yUeD+0uoGhDNesS6p3Q6RWJd7z2SwcSE+4CxE3JLzHmq/b9wMzLBaCjyF8XVszRY9QGvf+OrhvCXUiKGQxobWvAbkcqQ88tgqu5pAoGASttAirD52FQ3AENgjrd7bfWaHFm9nnagJsrNkm843pH/1eWUSHlVWaGkrk8sRAw3EiFL74tPIym8vVOPkYIOLJVqb6eqZ0JelsjOxac0qipA4zXPIaUIcHlEfevXKT/KcB4LfKc6mBTSlE0EBsc2LwC5N1v5KiLMckq3OScHGIkCgYANfP5cGyKySkn2BzTlILnWu+uPHuqaAIV6Fc+Z6h/WbdXw2opdEP3A7GEUQUY6fjYj6AD8Jutn3sz1yd7l5ly+TX6I6YFJ5xHcFcxvl9m/kZIbps+wUjn5mJYZaGcnm2ZYvUD+I0VERLX2yBWg0SWXGuY/Z3mwe4D8nJxZNC4o4g==";
        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjedhtEgisXmKUQ9B+P+IldGYB6Qmo8eZi5cZdJzXPDlDMwofCwQqr8+XTjbhhAWMkMdWbR+pewVjAjcelF0apeRyAJlf9rLi0fADc9XdK32fjPXyUKRRyUX5obguTNaC7w3DoQm5MYnxxaWStFisXkyrIKM3E5ibN0ansdCC8+zF5XfdOffEl/5ohgTM79l1e4LRM/O3ei52fs2Ip03coUrnfeWCvzActeLby+z1rFW9BY3u/DkcSlwAOl3XPIg1r9yulXSDm8W49TDvLgnMIEXyVoOgmjckyOl7vKWti9fiDJ+RnARve01EjIpZx5NNM1MuDx/4OkIiNydgTXJZ1wIDAQAB";
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipaydev.com/gateway.do");
        alipayConfig.setAppId("2021000121663960");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF8");
        alipayConfig.setSignType("RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
        model.setBillType("trade");
        model.setBillDate("2016-04-05");
        request.setBizModel(model);
        AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }
}
package com.alipay.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.resource.AliPayResource;
import com.alipay.utils.DateUtil;
import com.alipay.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author: HuGoldWater
 * @description:
 */
@Slf4j
@RestController
@RequestMapping("payment")
public class AlipayController {

    @Autowired
    private AliPayResource aliPayResource;

    /**
     * 前往支付宝进行支付
     */
    @GetMapping(value="/goAlipay")
    public JsonResult goAlipay(String merchantUserId, String merchantOrderId) throws Exception{
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayResource.getGatewayUrl(),
                aliPayResource.getAppId(),
                aliPayResource.getMerchantPrivateKey(),
                "json",
                aliPayResource.getCharset(),
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getSignType());

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(aliPayResource.getReturnUrl());
        alipayRequest.setNotifyUrl(aliPayResource.getNotifyUrl());

        // 商户订单号, 商户网站订单系统中唯一订单号, 必填
        String out_trade_no = merchantOrderId;
        // 付款金额, 必填 单位元
       String total_amount = "0.01";  // 测试用 1分钱
        // 订单名称, 必填
        String subject = "胡金水-付款用户[" + merchantUserId + "]";
        // 商品描述, 可空, 目前先用订单名称
        String body = subject;

        // 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
        String timeout_express = "1h";
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String alipayForm = "";
        try {
            alipayForm = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        log.info("支付宝支付 - 前往支付页面, alipayForm: \n{}", alipayForm);
        return JsonResult.ok(alipayForm);
    }


    /**
     * 支付成功后的支付宝异步通知
     */
    @RequestMapping(value="/alipay")
    public String alipay(HttpServletRequest request, HttpServletResponse response) throws Exception {

        log.info("支付成功后的支付宝异步通知");

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
//       valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params,
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getCharset(),
                aliPayResource.getSignType()); //调用SDK验证签名

        if(signVerified) {//验证成功
            // 商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
            // 付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

            if (trade_status.equals("TRADE_SUCCESS")){
//                String merchantReturnUrl = paymentOrderService.updateOrderPaid(out_trade_no, CurrencyUtils.getYuan2Fen(total_amount));
//                notifyFoodieShop(out_trade_no,merchantReturnUrl);
            }

            log.info("************* 支付成功(支付宝异步通知) - 时间: {} *************", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
            log.info("* 订单号: {}", out_trade_no);
            log.info("* 支付宝交易号: {}", trade_no);
            log.info("* 实付金额: {}", total_amount);
            log.info("* 交易状态: {}", trade_status);
            log.info("*****************************************************************************");

            return "success";
        }else {
            //验证失败
            log.info("验签失败, 时间: {}", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
            return "fail";
        }
    }

}

有关平台H5对接支付宝支付接口(含分布式源码)的更多相关文章

  1. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

  2. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  3. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  4. ruby-on-rails - 与 ActiveMerchant 一起使用的最佳支付网关是什么? - 2

    我需要使用ActiveMerchant库在我们的一个Rails应用程序中设置支付解决方案。尽管这个问题非常主观,但人们对主要网关(BrainTree、Authorize.net等)的体验如何?它必须:处理定期付款。有能力记入个人帐户。能够取消付款。有办法存储用户的付款详细信息(例如Authotize.netsCIM)。干杯 最佳答案 ActiveMerchant很棒,但在过去一年左右的时间里,我在使用它时发现了一些问题。首先,虽然某些网关可能会得到“支持”——但并非所有功能都包含在内。查看功能矩阵以确保完全支持您选择的网关-http

  5. elasticsearch源码关于TransportSearchAction【阶段三】 - 2

    1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>

  6. (附源码)vue3.0+.NET6实现聊天室(实时聊天SignalR) - 2

    参考文章搭建文章gitte源码在线体验可以注册两个号来测试演示图:一.整体介绍  介绍SignalR一种通讯模型Hub(中心模型,或者叫集线器模型),调用这个模型写好的方法,去发送消息。  内容有:    ①:Hub模型的方法介绍    ②:服务器端代码介绍    ③:前端vue3安装并调用后端方法    ④:聊天室样例整体流程:1、进入网站->调用连接SignalR的方法2、与好友发送消息->调用SignalR的自定义方法 前端通过,signalR内置方法.invoke()  去请求接口3、监听接受方法(渲染消息)通过new signalR.HubConnectionBuilder().on

  7. ruby-on-rails - 如何在 RubyOnRails 中使用 'acts as nested set' 创建一个可排序的接口(interface) - 2

    我一直在为使用acts_as_list的模型实现一些不错的交互界面,这些界面可以对我的mRails应用程序中的列表进行排序。我有一个排序函数,在每次拖放之后使用sortable_elementscript.aculo.us函数调用并设置每条记录的位置。这是在拖放完成后处理排序的Controller操作示例:defsortparams[:documents].each_with_indexdo|id,index|Document.update_all(['position=?',index+1],['id=?',id])endend现在我正在尝试对嵌套集模型(acts_as_nested

  8. ruby - 停止分布式 Ruby 服务 - 2

    我有一个启动DRb服务的脚本,然后生成处理程序对象并通过DRb.thread.join等待。我希望脚本一直运行直到被明确杀死,所以我添加了trap"INT"doDRb.stop_serviceend在Ruby1.8下成功停止DRb服务并退出,但在1.9下似乎死锁(在OSX10.6.7上)。对该进程进行采样显示在semaphore_wait_signal_trap中有几个线程在旋转。我假设我在调用stop_service时做错了什么,但我不确定是什么。谁能给我任何关于如何正确处理它的指示? 最佳答案 好的,我想我已经找到了解决方案。如

  9. Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理) - 2

    快速导航(持续更新中…)Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理)Cesium源码解析二(metadataAvailability的含义)Cesium源码解析三(metadata元数据拓展中行列号的分块规则解析)Cesium源码解析四(Quantized-Mesh(.terrain)格式文件在CesiumJS和UE中加载情况的对比)目录1.前言2.本篇的由来3.terrain文件的加载3.1更新环境3.2更新和执行渲染命令3.3数据优化3.4结束当前帧4.总结1.前言  目前市场上三维比较火的实现方案主要有两种,b/s的方案主要是Cesium,c/s的方案主要是u

  10. 你真正了解什么是接口测试么?接口实战一“篇”入魂 - 2

    最近在工作中,看到一些新手测试同学,对接口测试存在很多疑问,甚至包括一些从事软件测试3,5年的同学,在聊到接口时,也是一知半解;今天借着这个机会,对接口测试做个实战教学,顺便总结一下经验,分享给大家。计划拆分成4个模块跟大家做一个分享,(接口测试、接口基础知识、接口自动化、接口进阶)感兴趣的小伙伴记得关注,希望对你的日常工作和求职面试,带来一些帮助。注:文章较长有5000多字,希望小伙伴们认真看完,当然有些内容对小白同学不是太友好,如果你需要详细了解其中的一些概念或者名词,请在文章之后留言,后续我将针对大家的疑问,整理输出一些大家感兴趣的文章。随着开发模式的迭代更新,前后端分离已不是新的概念,

随机推荐