使用java实现对接 支付宝、微信、云闪付支付功能,前后端实现

一、前端实现

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&开发工具|微信支付商户文档中心

Maven Central: com.github.wechatpay-apiv3:wechatpay-javaDiscover wechatpay-java in the com.github.wechatpay-apiv3 namespace. Explore metadata, contributors, the Maven POM file, and more.icon-default.png?t=O83Ahttps://central.sonatype.com/artifact/com.github.wechatpay-apiv3/wechatpay-java

<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. 总结

通过以上步骤,我们成功实现了支付宝、微信和云闪付的支付功能集成。以下是整个支付系统的概览图:

这个架构展示了前端如何与后端支付服务进行交互,以及支付服务如何与不同的支付平台通信。你可以根据实际需求进一步扩展和完善这个支付系统 

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慧香一格

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值