一、前端实现
1. 初始化 Vue 3 项目
首先,确保你已经安装了 Vue CLI。如果没有安装,可以通过以下命令进行安装:
bash
npm install -g @vue/cli
然后创建一个新的 Vue 3 项目:
bash
vue create payment-frontend
cd payment-frontend
在创建过程中选择默认的 Vue 3 预设或其他你需要的配置。
2. 安装 Axios
Axios 是一个常用的 HTTP 客户端,用于发送请求到后端 API。
bash
npm install axios
3. 创建支付组件
3.1 商品列表页面
创建一个 ProductList.vue
组件来显示商品列表,并提供支付按钮。
html
<template>
<div class="product-list">
<h1>Available Products</h1>
<ul>
<li v-for="product in products" :key="product.id" class="product-item">
<h2>{{ product.name }}</h2>
<p>Price: ${{ product.price }}</p>
<p>Stock: {{ product.stock }}</p>
<button @click="payWithAlipay(product.id)">Pay with Alipay</button>
<button @click="payWithWeChat(product.id)">Pay with WeChat</button>
<button @click="payWithUnionPay(product.id)">Pay with UnionPay</button>
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
products: [],
};
},
created() {
this.fetchProducts();
},
methods: {
async fetchProducts() {
try {
const response = await axios.get('http://localhost:8080/api/products?page=0&size=10');
this.products = response.data;
} catch (error) {
console.error('Error fetching products:', error);
}
},
async payWithAlipay(productId) {
try {
const response = await axios.post(`http://localhost:8080/api/pay/alipay`, { productId });
document.body.innerHTML = response.data; // Render the form returned by Alipay
} catch (error) {
console.error('Payment failed:', error);
}
},
async payWithWeChat(productId) {
try {
const response = await axios.post(`http://localhost:8080/api/pay/wechat`, { productId });
window.location.href = response.data.url; // Redirect to WeChat payment page
} catch (error) {
console.error('Payment failed:', error);
}
},
async payWithUnionPay(productId) {
try {
const response = await axios.post(`http://localhost:8080/api/pay/unionpay`, { productId });
document.body.innerHTML = response.data; // Render the form returned by UnionPay
} catch (error) {
console.error('Payment failed:', error);
}
},
},
};
</script>
<style scoped>
.product-list {
padding: 20px;
}
.product-item {
border-bottom: 1px solid #ccc;
padding: 10px 0;
}
.product-item button {
margin-top: 10px;
padding: 5px 10px;
cursor: pointer;
}
</style>
3.2 主页路由配置
修改 src/router/index.js
文件以包含 ProductList
组件。
js
import { createRouter, createWebHistory } from 'vue-router';
import ProductList from '../components/ProductList.vue';
const routes = [
{
path: '/',
name: 'ProductList',
component: ProductList,
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
3.3 修改 App.vue
确保 App.vue
正确引入并使用路由。
html
<template>
<router-view></router-view>
</template>
<script>
export default {
name: 'App',
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
4. 运行前端应用
确保你的后端服务正在运行,然后启动前端应用:
bash
npm run serve
打开浏览器访问 http://localhost:8081
(假设前端服务运行在 8081 端口),你应该能看到商品列表和支付按钮。
二、后端实现
实现支付宝、微信和云闪付的支付功能需要与各自的支付平台进行集成。每个支付平台都有其特定的 API 文档和 SDK,因此我们需要按照官方文档进行开发。以下是针对这三个支付平台的基本集成步骤。
1. 支付宝支付集成
1.1 获取支付宝商户信息
- 注册成为支付宝开放平台开发者。
- 创建应用并获取
AppID
。 - 获取
私钥
和公钥
。 - 配置回调 URL。
1.2 引入依赖
在 pom.xml
中添加支付宝 SDK 依赖:
xml
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.10.117.ALL</version>
</dependency>
这里可参考官网的引用:小程序文档 - 支付宝文档中心
Maven Central: com.alipay.sdk:alipay-sdk-java
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.33.ALL</version>
</dependency>
1.3 配置支付宝参数
创建一个配置类来存储支付宝相关的配置信息。
java
package com.seckillsystem.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
private String appId;
private String merchantPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
private String returnUrl;
private String gatewayUrl;
// Getters and Setters
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getMerchantPrivateKey() {
return merchantPrivateKey;
}
public void setMerchantPrivateKey(String merchantPrivateKey) {
this.merchantPrivateKey = merchantPrivateKey;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public void setAlipayPublicKey(String alipayPublicKey) {
this.alipayPublicKey = alipayPublicKey;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public String getReturnUrl() {
return returnUrl;
}
public void setReturnUrl(String returnUrl) {
this.returnUrl = returnUrl;
}
public String getGatewayUrl() {
return gatewayUrl;
}
public void setGatewayUrl(String gatewayUrl) {
this.gatewayUrl = gatewayUrl;
}
}
1.4 编写支付服务
创建一个服务类来处理支付宝支付请求。
java
package com.seckillsystem.service;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.seckillsystem.config.AlipayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Service
public class AlipayService {
@Autowired
private AlipayConfig alipayConfig;
public String pay(Long orderId, Double amount, String subject, String body) throws AlipayApiException {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(alipayConfig.getReturnUrl());
request.setNotifyUrl(alipayConfig.getNotifyUrl());
Map<String, Object> bizContent = new HashMap<>();
bizContent.put("out_trade_no", orderId.toString());
bizContent.put("total_amount", amount.toString());
bizContent.put("subject", subject);
bizContent.put("body", body);
request.setBizContent(JSON.toJSONString(bizContent));
return AlipaySignature.rsaSign(request.getBizContent(), alipayConfig.getMerchantPrivateKey(), "UTF-8", "RSA2");
}
public boolean verify(HttpServletRequest request) throws Exception {
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = iter.next();
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
String sign = params.get("sign");
params.remove("sign");
params.remove("sign_type");
return AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
}
}
1.5 控制器层
创建控制器来处理支付请求和回调。
java
package com.seckillsystem.controller;
import com.seckillsystem.service.AlipayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
public class AlipayController {
@Autowired
private AlipayService alipayService;
@PostMapping("/pay/alipay")
public void pay(@RequestParam Long orderId, @RequestParam Double amount, @RequestParam String subject, @RequestParam String body, HttpServletResponse response) throws IOException {
try {
String form = alipayService.pay(orderId, amount, subject, body);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(form);
response.getWriter().flush();
} catch (Exception e) {
e.printStackTrace();
}
}
@PostMapping("/notify/alipay")
public String notify(HttpServletRequest request) {
try {
if (alipayService.verify(request)) {
// Process payment success logic here
return "success";
} else {
return "failure";
}
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
}
}
2. 微信支付集成
2.1 获取微信商户信息
- 注册成为微信支付商户。
- 获取
商户号
和API 密钥
。 - 配置回调 URL。
2.2 引入依赖
在 pom.xml
中添加微信支付 SDK 依赖:
xml
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient-v3</artifactId>
<version>0.2.1</version>
</dependency>
参考官网的说明:SDK_SDK&开发工具|微信支付商户文档中心
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.15</version>
</dependency>
2.3 配置微信支付参数
创建一个配置类来存储微信支付相关的配置信息。
java
package com.seckillsystem.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "wechatpay")
public class WeChatPayConfig {
private String mchId;
private String serialNo;
private String privateKeyPath;
private String apiv3Key;
private String notifyUrl;
// Getters and Setters
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getSerialNo() {
return serialNo;
}
public void setSerialNo(String serialNo) {
this.serialNo = serialNo;
}
public String getPrivateKeyPath() {
return privateKeyPath;
}
public void setPrivateKeyPath(String privateKeyPath) {
this.privateKeyPath = privateKeyPath;
}
public String getApiv3Key() {
return apiv3Key;
}
public void setApiv3Key(String apiv3Key) {
this.apiv3Key = apiv3Key;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
}
2.4 编写支付服务
创建一个服务类来处理微信支付请求。
java
package com.seckillsystem.service;
import com.github.wechatpay.apiv3.WechatPayHttpClientBuilder;
import com.github.wechatpay.apiv3.auth.AutoUpdateCertificatesVerifier;
import com.github.wechatpay.apiv3.auth.PrivateKeySigner;
import com.github.wechatpay.apiv3.cert.CertificatesManager;
import com.github.wechatpay.apiv3.cert.WechatPay2Credentials;
import com.github.wechatpay.apiv3.exception.MalformedMessageException;
import com.github.wechatpay.apiv3.exception.ServiceException;
import com.github.wechatpay.apiv3.exception.ValidationException;
import com.github.wechatpay.apiv3.resources.payscore.Transaction;
import com.github.wechatpay.apiv3.services.PayScoreService;
import com.seckillsystem.config.WeChatPayConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
@Service
public class WeChatPayService {
@Autowired
private WeChatPayConfig weChatPayConfig;
private CloseableHttpClient httpClient;
private CertificatesManager certificatesManager;
public WeChatPayService() {
PrivateKey merchantPrivateKey = loadPrivateKey(weChatPayConfig.getPrivateKeyPath());
X509Certificate certificate = loadCertificate(weChatPayConfig.getCertificatePath());
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(weChatPayConfig.getMchId(), new PrivateKeySigner(weChatPayConfig.getSerialNo(), merchantPrivateKey)),
certificate.getX509Certificate()
);
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(weChatPayConfig.getMchId(), weChatPayConfig.getSerialNo(), merchantPrivateKey)
.withValidator(new CustomHttpServletResponseValidator())
.withSigner(verifier)
.build();
certificatesManager = verifier.getUpdater().getCertificatesManager();
}
public Transaction createTransaction(Long orderId, Double amount, String description) throws ValidationException, ServiceException, MalformedMessageException {
PayScoreService service = new PayScoreService(httpClient, certificatesManager);
Transaction transaction = new Transaction();
transaction.setOutOrderNo(orderId.toString());
transaction.setTimeExpire("2025-12-31T23:59:59+08:00");
transaction.setAttach("附加信息");
transaction.setDescription(description);
transaction.setAmount(Transaction.Amount.builder().total((long) (amount * 100)).currency("CNY").build());
transaction.setSceneInfo(Transaction.SceneInfo.builder().payerClientId("user_openid").build());
return service.create(transaction);
}
public boolean verify(Map<String, String> headers, String body) {
try {
return certificatesManager.verify(headers, body.getBytes(StandardCharsets.UTF_8));
} catch (ValidationException | MalformedMessageException e) {
e.printStackTrace();
return false;
}
}
private PrivateKey loadPrivateKey(String filePath) {
// Load private key from file
return null;
}
private X509Certificate loadCertificate(String filePath) {
// Load certificate from file
return null;
}
}
2.5 控制器层
创建控制器来处理支付请求和回调。
java
package com.seckillsystem.controller;
import com.seckillsystem.service.WeChatPayService;
import com.github.wechatpay.apiv3.resources.payscore.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RestController
public class WeChatPayController {
@Autowired
private WeChatPayService weChatPayService;
@PostMapping("/pay/wechat")
public Transaction pay(@RequestParam Long orderId, @RequestParam Double amount, @RequestParam String description) {
try {
return weChatPayService.createTransaction(orderId, amount, description);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@PostMapping("/notify/wechat")
public String notify(HttpServletRequest request) {
try {
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String body = sb.toString();
Map<String, String> headers = new HashMap<>();
headers.put("Wechatpay-Signature", request.getHeader("Wechatpay-Signature"));
headers.put("Wechatpay-Timestamp", request.getHeader("Wechatpay-Timestamp"));
headers.put("Wechatpay-Nonce", request.getHeader("Wechatpay-Nonce"));
headers.put("Wechatpay-Serial", request.getHeader("Wechatpay-Serial"));
if (weChatPayService.verify(headers, body)) {
// Process payment success logic here
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
} else {
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[Invalid signature]]></return_msg></xml>";
}
} catch (IOException e) {
e.printStackTrace();
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[IO Error]]></return_msg></xml>";
}
}
}
3. 云闪付支付集成
3.1 获取云闪付商户信息
- 注册成为银联商户。
- 获取
商户号
和API 密钥
。 - 配置回调 URL。
3.2 引入依赖
在 pom.xml
中添加云闪付 SDK 依赖:
xml
<dependency>
<groupId>com.unionpay.acp</groupId>
<artifactId>acp-core</artifactId>
<version>5.1.0</version>
</dependency>
官方接入文档说明:https://open.unionpay.com/tjweb/acproduct/list?apiSvcId=449&index=5
或者 源代码下载 后,将源码转jar包
注:
在Maven项目中引入银联商户SDK依赖,通常需要找到相应的依赖在Maven中央仓库的坐标,然后在项目的pom.xml
文件中添加。由于银联商户SDK可能不在公共Maven仓库中,你可能需要手动下载JAR包并添加到本地Maven仓库,或者使用项目内的lib
目录并通过systemPath
指定。
以下是一个示例,假设你已经下载了银联商户SDK的JAR包并添加到了本地Maven仓库:
xml
<dependencies>
<!-- 添加银联商户SDK依赖 -->
<dependency>
<groupId>com.unionpay</groupId>
<artifactId>unionpay-sdk</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
如果你没有在Maven中央仓库找到坐标,可以通过以下方式添加:
xml
<dependencies>
<!-- 添加本地SDK依赖 -->
<dependency>
<groupId>com.unionpay</groupId>
<artifactId>unionpay-sdk</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/unionpay-sdk.jar</systemPath>
</dependency>
</dependencies>
在这个例子中,unionpay-sdk.jar
应该放在项目目录下的 lib
文件夹中。
请注意,使用systemPath
是不推荐的,因为它会破坏构建的可移植性。更好的做法是将依赖的JAR上传到你自己的Maven仓库,或者使用Nexus、Artifactory等仓库管理器来托管第三方依赖。
3.3 配置云闪付参数
创建一个配置类来存储云闪付相关的配置信息。
java
package com.seckillsystem.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "unionpay")
public class UnionPayConfig {
private String merId;
private String certId;
private String frontUrl;
private String backUrl;
private String signCertPath;
private String validateCertDir;
// Getters and Setters
public String getMerId() {
return merId;
}
public void setMerId(String merId) {
this.merId = merId;
}
public String getCertId() {
return certId;
}
public void setCertId(String certId) {
this.certId = certId;
}
public String getFrontUrl() {
return frontUrl;
}
public void setFrontUrl(String frontUrl) {
this.frontUrl = frontUrl;
}
public String getBackUrl() {
return backUrl;
}
public void setBackUrl(String backUrl) {
this.backUrl = backUrl;
}
public String getSignCertPath() {
return signCertPath;
}
public void setSignCertPath(String signCertPath) {
this.signCertPath = signCertPath;
}
public String getValidateCertDir() {
return validateCertDir;
}
public void setValidateCertDir(String validateCertDir) {
this.validateCertDir = validateCertDir;
}
}
3.4 编写支付服务
创建一个服务类来处理云闪付支付请求。
package com.seckillsystem.service;
import com.unionpay.acp.sdk.AcpService;
import com.unionpay.acp.sdk.LogUtil;
import com.unionpay.acp.sdk.SDKConstants;
import com.seckillsystem.config.UnionPayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class UnionPayService {
@Autowired
private UnionPayConfig unionPayConfig;
public String pay(Long orderId, Double amount, String orderDesc) {
Map<String, String> requestData = new HashMap<>();
/***银联全渠道系统固定值***/
requestData.put(SDKConstants.VERSION, SDKConstants.VERSION_5_1_0); //版本号
requestData.put(SDKConstants.ENCODE, SDKConstants.UTF_8_ENCODING); //字符集编码 可以使用UTF-8,GBK两种方式
requestData.put(SDKConstants.SIGN_METHOD, SDKConstants.SIGNMETHOD_RSA); //签名方法
requestData.put(SDKConstants.TRADE_TYPE, SDKConstants.TRADE_TYPE_APP); //交易类型 一般为01代表消费
/***商户接入参数***/
requestData.put(SDKConstants.MER_ID, unionPayConfig.getMerId()); //商户号码,请改成自己申请的商户号或者open上注册得来的777商户号测试
requestData.put(SDKConstants.ACCESS_TYPE, "0"); //接入类型,商户接入固定填0,不需修改
requestData.put(SDKConstants.ACCEPT_ORDER, "Y"); //是否接受后台通知 Y/N 默认Y
requestData.put(SDKConstants.LANGUAGE, "ZH"); //语言种类 ZH-中文 EN-英文 默认中文
/***订单相关参数***/
requestData.put(SDKConstants.ORDER_ID, orderId.toString()); //商户订单号,8-32位数字字母,不能含“-”或“_”
requestData.put(SDKConstants.SUBJECT, orderDesc); //商品描述
requestData.put(SDKConstants.BODY, orderDesc); //商品描述
requestData.put(SDKConstants.TRANS_TYPE, "01"); //交易类型 01:消费
requestData.put(SDKConstants.TRADE_TIME, AcpService.getCurrentTime()); //订单发送时间,格式为yyyyMMddHHmmss,必须取当前时间,否则会报错
requestData.put(SDKConstants.AMT, String.valueOf(amount * 100)); //交易金额 单位为分 必须是整数
requestData.put(SDKConstants.CURRENCY_CODE, "156"); //境内商户固定填写156 人民币
/***前台通知地址(验签)后缀不要带问号**/
requestData.put(SDKConstants.FRONT_URL, unionPayConfig.getFrontUrl()); //前台通知地址 (需设置为外网能访问 http https均可),支付成功后的页面跳转路径
/***后台通知地址(验签)后台通知参数同前台通知参数**//***
* 后台可通知地址如果支持http协议 那可以传入http://域名/接收背景通知接口地址 如果仅支持https 则必须传入https://域名/接收后台通知接口地址
* 在本项目中后台通知参数在doPost方法中获取解析
*/
requestData.put(SDKConstants.BACK_URL, unionPayConfig.getBackUrl()); //后台通知地址 (需设置为外网能访问 http https均可)
/***要调通交易以下字段必须正确填充***/
// 请求方保留域,
// 填写请求时,如不希望被银联透传可以不填,商户自定义用作请求标识
// 前后台通知商户根据该标识做关联定位 建议使用全局唯一标识 如分布式系统可用雪花算法等
requestData.put(SDKConstants.RESERVED_FIELD1, orderId.toString());
/***银联测试环境 开始***/
String reqMessage = AcpService.map2HtmlForm(requestData, unionPayConfig.getSignCertPath(), unionPayConfig.getCertId(), unionPayConfig.getEncode());
LogUtil.writeLog("打印请求HTML,此html生成后,您只要原样输出到浏览器即可完成付款操作:" + reqMessage);
/***银联测试环境 结束***/
return reqMessage;
}
public boolean verify(Map<String, String> respData) {
if (!AcpService.validate(respData, unionPayConfig.getValidateCertDir())) {
LogUtil.writeErrorLog("验证签名结果[失败].");
return false;
}
LogUtil.writeLog("验证签名结果[成功].");
return true;
}
}
3.5 控制器层
创建控制器来处理支付请求和回调。
java
package com.seckillsystem.controller;
import com.seckillsystem.service.UnionPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RestController
public class UnionPayController {
@Autowired
private UnionPayService unionPayService;
@PostMapping("/pay/unionpay")
public void pay(@RequestParam Long orderId, @RequestParam Double amount, @RequestParam String orderDesc, HttpServletResponse response) throws IOException {
String form = unionPayService.pay(orderId, amount, orderDesc);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(form);
response.getWriter().flush();
}
@PostMapping("/notify/unionpay")
public String notify(HttpServletRequest request) {
try {
Map<String, String> respData = getAllRequestParam(request);
if (unionPayService.verify(respData)) {
// Process payment success logic here
return "ok";
} else {
return "fail";
}
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
private Map<String, String> getAllRequestParam(final HttpServletRequest request) {
Map<String, String> res = new HashMap<>();
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : parameterMap.keySet()) {
String[] values = parameterMap.get(key);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < values.length; i++) {
if (i == values.length - 1) {
builder.append(values[i]);
} else {
builder.append(values[i]).append(",");
}
}
res.put(key, builder.toString());
}
return res;
}
}
4. 总结
通过以上步骤,我们成功实现了支付宝、微信和云闪付的支付功能集成。以下是整个支付系统的概览图:
这个架构展示了前端如何与后端支付服务进行交互,以及支付服务如何与不同的支付平台通信。你可以根据实际需求进一步扩展和完善这个支付系统