引言
本文代码已提交至Github(版本号:
256c7e9012276479da34d7d07fba707eb955710a
),有兴趣的同学可以下载来看看:https://github.com/ylw-github/taodong-shop
阅读本文前,有兴趣的同学可以参考我之前写的聚合支付的文章:
- 《淘东电商项目(52) -聚合支付开篇》
- 《淘东电商项目(53) -银联支付案例源码分析》
- 《淘东电商项目(54) -银联支付案例(同步与异步)》
- 《淘东电商项目(55) -支付系统核心表设计》
- 《淘东电商项目(56) -支付系统分布式事务的解决方案》
- 《淘东电商项目(57) -聚合支付(支付令牌接口)》
- 《淘东电商项目(58) -聚合支付(基于设计模式自动跳转支付接口)》
- 《淘东电商项目(59) -聚合支付(集成银联支付)》
目前「淘东电商项目」的聚合支付模块,已经完成了银联支付的集成,接下来主要讲解集成支付宝,其实支付宝集成的原理跟银联支付大同小异,接下来不会详细的描述其细节代码,直接讲解集成流程。
本文目录结构:
1. 支付宝沙箱环境相关申请
1.1 Demo下载地址以及沙箱环境
本文不专门讲解支付宝Demo源码,有兴趣的同学们可以下载来自己看案例源码,支付宝案例SDK下载地址:https://docs.open.alipay.com/270/106291/
使用支付宝直接扫码进入沙箱环境即可配置,支付宝沙箱环境:https://openhome.alipay.com/platform/appDaily.htm
1.2 沙箱环境配置
扫码进入后,选择“自研开发服务”,并填写个人的相关信息:
点击确认之后,会进入沙箱配置环境:
公钥和秘钥使用支付宝的生成工具生成,本文不再详述,具体可以参考我的博客:《如何配置支付宝沙箱环境》。
2. 项目集成
1.新增taodong-shop-alipay-plugin
插件模块:
2.新增模块添加maven依赖:
<dependencies> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>3.7.4.ALL</version> </dependency> </dependencies>
3.增加配置文件(这里其实是从Demo里复制过来的,如果配置的话,只需要配置前三个即可):
public class AlipayConfig { //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 public static String app_id = ""; // 商户私钥,您的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 = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp"; // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String return_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp"; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String charset = "utf-8"; // 支付宝网关 public static String gatewayUrl = "https://openapi.alipay.com/gateway.do"; // 支付宝网关 public static String log_path = "C:\\"; //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ /** * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库) * @param sWord 要写入日志里的文本内容 */ public static void logResult(String sWord) { FileWriter writer = null; try { writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt"); writer.write(sWord); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
4.支付服务,完善支付宝支付策略者AliPayStrategy
代码:
/** * description: 支付宝支付渠道 * create by: YangLinWei * create time: 2020/5/13 4:41 下午 */ @Slf4j public class AliPayStrategy implements PayStrategy { @Override public String toPayHtml(PaymentChannelEntity pymentChannel, PayMentTransacDTO payMentTransacDTO) { log.info(">>>>>支付宝参数封装开始<<<<<<<<"); // 获得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); // 设置请求参数 AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url); // 商户订单号,商户网站订单系统中唯一订单号,必填 String outTradeNo = payMentTransacDTO.getPaymentId(); // 付款金额,必填 String totalAmount = changeF2Y(payMentTransacDTO.getPayAmount() + ""); // 订单名称,必填 String subject = payMentTransacDTO.getProductName(); // 商品描述,可空 String body = payMentTransacDTO.getProductName()+"很不错,值得购买!"; alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"total_amount\":\"" + totalAmount + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); // 请求 try { String result = alipayClient.pageExecute(alipayRequest).getBody(); return result; } catch (Exception e) { return null; } } /** 金额为分的格式 */ public static final String CURRENCY_FEN_REGEX = "\\-?[0-9]+"; /** * 将分为单位的转换为元 (除100) * * @param amount * @return * @throws Exception */ public static String changeF2Y(String amount) { if (!amount.matches(CURRENCY_FEN_REGEX)) { return null; } return BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100)).toString(); } }
3. 测试
首先启动项目(Eureka注册中心、单点服务中心、会员服务、支付服务、支付门户):
2.复制token,跳转到支付详情页,浏览器输入:http://localhost:8079/pay?payToken=pay_e18fe21f43f24fbca8e9a7c3755b58fc
3.点击支付宝进行支付,会跳转到如下页面: