2、代码开发
2.1 引入java sdk包
<dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>3.7.26.ALL</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency>
2.2 开发配置类
package com.shop.constants; /** *类名:AlipayConfig *功能:基础配置类 *详细:设置帐户有关信息及返回路径 *修改日期:2019-04-30 *说明: *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 */ public class AlipayConfig { //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 public static String app_id = "20160******"; // 商户私钥,您的PKCS8格式RSA2私钥 public static String merchant_private_key = "*******"; // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 public static String alipay_public_key = "********"; // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String notify_url = "https://www.alipay.com"; // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,沙箱环境下可以填写本地地址 public static String return_url = "http://localhost:8082/web/pay/callback"; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String charset = "utf-8"; // 支付宝网关 public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; //销售产品码,商家和支付宝签约的产品码,默认值为:QUICK_WAP_WAY public static String productCode ="QUICK_WAP_WAY"; //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ }
2.3 开发工具类
import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; 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.AlipayTradeRefundRequest; import com.alipay.api.request.AlipayTradeWapPayRequest; import com.shop.constants.AlipayConfig; import com.shop.constants.BakConstants; public class PayUtil { /** * @Title: alipay * @Description: TODO(支付) * @param outTradeNo 商户订单号,商户网站订单系统中唯一订单号,必填 对应缴费记录的orderNo * @param totalAmount 付款金额,必填 * @param subject 主题 * @param body 商品描述,可空 * @param: @return * @param: @throws Exception * @return: String * @throws */ public static String alipay(String outTradeNo,String totalAmount,String subject,String body) throws Exception{ //获得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //该笔订单允许的最晚付款时间 String timeout=30m; //设置请求参数 String content = "{\"out_trade_no\":\""+ outTradeNo +"\"," + "\"total_amount\":\""+ totalAmount +"\"," + "\"subject\":\""+ subject +"\"," + "\"timeout_express\":\""+ timeout +"\"," + "\"body\":\""+ body +"\"," + "\"product_code\":\""+AlipayConfig.productCode+"\"}"; AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url); alipayRequest.setBizContent(content); //请求 String result=""; result = alipayClient.pageExecute(alipayRequest).getBody(); return result; } /** * 支付宝退款接口 * @param outTradeNo * @param tradeNo * @param refundAmount * @param refundReason * @param out_request_no 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传 * @return */ public static String aliRefund(String outTradeNo,String tradeNo,String refundAmount,String refundReason,String out_request_no) { //获得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //设置请求参数 AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url); try { alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\"," + "\"trade_no\":\""+ tradeNo +"\"," + "\"refund_amount\":\""+ refundAmount +"\"," + "\"refund_reason\":\""+ refundReason +"\"," + "\"out_request_no\":\""+ out_request_no +"\"}"); //请求 String result; //请求 result = alipayClient.execute(alipayRequest).getBody(); System.out.println("*********************\n返回结果为:"+result); return result; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } /** * 支付宝的验签方法 * @param req * @return */ public static boolean checkSign(HttpServletRequest req) { Map<String, String[]> requestMap = req.getParameterMap(); Map<String, String> paramsMap = new HashMap<>(); requestMap.forEach((key, values) -> { String strs = ""; for(String value : values) { strs = strs + value; } System.out.println(("key值为"+key+"value为:"+strs)); paramsMap.put(key, strs); }); //调用SDK验证签名 try { return AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); } catch (AlipayApiException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("*********************验签失败********************"); return false; } } }
2.4、此时,即可打开支付宝登录页面。在手机端访问可以打开支付宝客户端
2.5、回调方法和支付完成的返回方法。
回调的方法是在AlipayConfig 类下有个return_url 是该应用回调的地址
2.6、回调接收参数:
import java.math.BigDecimal; public class AlipayNotifyParam { private String charset;//编码格式 private String out_trade_no;//商户网站唯一订单号 private String trade_no;//该交易在支付宝系统中的交易流水号。最长64位 private String method; private BigDecimal total_amount;//该笔订单的资金总额 private String sign;//签名结果 private String auth_app_id; private String app_id;//支付宝分配给开发者的应用Id private String sign_type;//签名类型 private String seller_id;//收款支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字 private String timestamp;//时间 //get和set省略 }
3、沙箱环境
在开发中心-》研发服务-》沙箱
沙箱:https://docs.open.alipay.com/200/105311/
简单而言就是支付宝测试环境 ,有一个沙箱账号:买家账号和一个卖家账号,可以进行模拟支付