支付接口(采用第三方收款系统)实现心得

前言 

        假如想通过手机扫码把钱转入银行账号,除了直接跟银行做接口。可以选择第三方支付平台,常见的有微信、支付宝、银联等,他们都跟各个银行做好了接口,通过平台接口对接就不用考虑各家银行接口。当然,带来了技术简便,额外要付出手续费。

        还有一种支付平台,他们整合了第三方支付平台,调用一个接口,可以实现微信、支付宝、银联等,实现手机扫码支付把钱转账到指定银行账号。商联通付就是其中一个,我们现在详细讨论下,这些接口如何实现。

 接口实现思路

假如我们去买东西,一般做以下操作步骤:
1、弹出支付二维码
2、手机扫二维码支付
3、手机接收支付结果信息

作为程序员,可能就需要多考虑几步,先通过泳道图,看下系统与平台之间的联系:

备注:

1、服务/pc端指的是业务系统,实际就是业务系统与平台做个接口,需要手机端扫码支付

2、回调地址是由服务(业务系统)提供,由平台接收到手机支付后,异步回调(异步同步主要由平台决定)

3、支付地址,其实就是手机端支付页面。为了提供手机扫码支付,就需要把支付地址转为二维码,供手机扫码。

技术实现,主要解决两个问题

1、回调地址,需要跳过权限限制(账号、密码)检测

2、返回支付地址,需要转为二维码图片,就需要转为图片地址

具体代码如下:

1、异步回调地址,需要跳过用户检测,spring mvc 配置代码如下:
/**
 * spring mvc 的框架配置
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Autowired private WebsiteTokenInterceptor websiteTokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 回调地址:Constants.URL_PREFIX + "/exam_pay/callback"
        registry.addInterceptor(websiteTokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(
                        Constants.URL_PREFIX + "/exam_pay/callback",
                );
    }

}

2、支付地址转为二维码的代码实现:

    /**
     * 根据回调地址生成二维码(返回base64图片地址)
     */
    public String getPayQrcode(String receiveUrl) {
        if (Strings.isNullOrEmpty(receiveUrl))
            BusinessException.throwConstraintException("无法完成操作,没有返回回调地址,无法生成二维码");

        try {
            log.debug("公开招聘缴费,返回二维码地址 = {}", receiveUrl);

            byte[] qrCode = getBase64QRCode(receiveUrl, RenderQrCodeOptions.DEFAULT);
            String qrCodeString = Encodes.encodeBase64(qrCode);

            return "data:image/png;base64,".concat(qrCodeString);
        } catch (WriterException e) {
            log.warn("二维码生成失败:{}/{}", e.getClass(), e.getLocalizedMessage());
            BusinessException.throwConstraintException("无法完成操作,二维码生成失败");
        }

        return null;
    }


    /**
     * 生成Base64的二维码
     */
    public static byte[] getBase64QRCode(String content, RenderQrCodeOptions options) throws WriterException {
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

        Map<EncodeHintType, Object> hints = new HashMap<>();
        //设置二维码四周白色区域的大小
        hints.put(EncodeHintType.MARGIN, options.getMargin());
        //设置二维码的容错性
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.values()[options.getCorrectionLevel()]);
        //画二维码
        BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, options.getWidth(), options.getHeight(), hints);
        BufferedImage image = toBufferedImage(bitMatrix);
        //注意此处拿到字节数据
        return imageToBytes(image, FORMAT_NAME);
    }

    /**
     * BufferedImage转Bytes
     */
    private static byte[] imageToBytes(BufferedImage image, String format) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, format, out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用支付宝沙箱生成收款码的代码实现: ``` python import requests # 支付宝沙箱接口地址 url = "https://openapi.alipaydev.com/gateway.do" # 支付宝沙箱应用的APPID app_id = "你的APPID" # 支付宝沙箱应用的私钥 app_private_key = """ -----BEGIN RSA PRIVATE KEY----- 你的私钥 -----END RSA PRIVATE KEY----- """ # 支付宝沙箱应用的公钥 alipay_public_key = """ -----BEGIN PUBLIC KEY----- 支付宝公钥 -----END PUBLIC KEY----- """ # 构建请求参数 params = { "app_id": app_id, "method": "alipay.marketing.cashlessvoucher.template.create", "format": "JSON", "charset": "utf-8", "sign_type": "RSA2", "timestamp": "2022-01-01 00:00:00", "version": "1.0", "biz_content": { "template_name": "测试收款码", "voucher_type": "cashless", "brand_name": "测试品牌", "voucher_desc": "测试描述", "publish_start_time": "2022-01-01 00:00:00", "publish_end_time": "2023-01-01 00:00:00", "use_rule": { "use_condition": { "suit_shops": { "shop_id": [ "001", "002", "003" ] } } } } } # 生成签名 from urllib.parse import quote_plus from hashlib import sha256 from base64 import encodebytes from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 sign_params = "&".join("{}={}".format(k, quote_plus(str(v))) for k, v in sorted(params.items())) sign_string = "&".join(["POST", quote_plus("/gateway.do"), quote_plus(sign_params)]) sign_key = RSA.import_key(app_private_key) signer = PKCS1_v1_5.new(sign_key) signature = encodebytes(signer.sign(sha256(sign_string.encode("utf-8")))).decode("utf-8").replace("\n", "") # 发送请求 headers = { "Content-Type": "application/json;charset=utf-8", } data = { **params, "sign": signature, } response = requests.post(url, headers=headers, json=data) # 解析响应 import json response_data = json.loads(response.content.decode("utf-8")) qr_code = response_data["alipay_cashless_voucher_template_create_response"]["qr_code"] print(qr_code) ``` 在上面的代码中,我们通过 `alipay.marketing.cashlessvoucher.template.create` 接口创建了一个无需现金支付的优惠券模板,并生成了一个收款码。其中,我们需要将支付宝沙箱应用的APPID、私钥和公钥替换成自己的。 成功执行后,会输出生成的收款码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值