fly coding 支付插件,Android 对接支付宝App支付

337 阅读2分钟

此前,已设计过多应用多平台支付模块的基础开篇。传送门

本篇,准备对接支付宝App支付基础模块,并基于此模块实现具体的业务功能逻辑。

实现思路

一、前期准备工作

1、参考网址

支付宝文档写的已经很详细了,就不多赘述了,传送门

二、后端功能开发

1、定义yml配置文件

  • 需求分析,思路梳理

通过阅读支付宝官方文档,梳理以下参数需要动态配置。开放平台APP Id、公钥、私钥、阿里公钥key。其中,由于公、私钥内容比较大,我准备采用文件路径配置方式存储,其他的则采用yml形式配置。

  • 配置示例如下

1、yml配置示例

2、密钥文件配置示例

2、实现下单扩展

  • 引用V3支付jar
<!-- 支付宝支付sdk -->
<dependency>
  <groupId>com.alipay.sdk</groupId>
  <artifactId>alipay-sdk-java</artifactId>
  <version>4.34.90.ALL</version>
</dependency>
  • 代码实现如下
package com.flycoding.biz.order.factory.impl.ali;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.flycoding.biz.order.config.OrderDictConfig;
import com.flycoding.biz.order.config.extend.PaymentExtend;
import com.flycoding.biz.order.entity.OrderInfo;
import com.flycoding.biz.order.enums.PayWay;
import com.flycoding.biz.order.factory.impl.base.BasePaymentFactory;
import com.flycoding.biz.order.utils.PayUtils;
import com.flycoding.drivenlibrary.engine.config.constants.DrivenConstants;
import com.flycoding.drivenlibrary.enums.ResponseResult;
import com.flycoding.drivenlibrary.exception.ResponseException;
import com.flycoding.drivenlibrary.factory.OpenPlatformConfig;
import com.flycoding.utillibrary.java.ArrayUtils;
import com.flycoding.utillibrary.strings.StringUtils;

import java.util.List;

/**
 * 支付宝app支付
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/12/7 20:46
 * @Copyright(C): 2022 by 赵屈犇
 */
@PaymentExtend(OrderDictConfig.PayWay.ALI_APP_API)
public class AliAppPaymentFactory extends BasePaymentFactory<AlipayTradeAppPayResponse> {

    @Override
    public AlipayTradeAppPayResponse placeOrder(OrderInfo orderInfo, OpenPlatformConfig platform) throws Exception {
        String appId = platform.getConfig(DrivenConstants.PlatformConstants.AliPayConstants.OPEN_APP_ID);
        String publicKey = platform.getSecretConfig(DrivenConstants.PlatformConstants.AliPayConstants.APP_PUBLIC_KEY);
        String privateKey = platform.getSecretConfig(DrivenConstants.PlatformConstants.AliPayConstants.APP_PRIVATE_KEY);
        if (StringUtils.isEmptys(appId, privateKey, publicKey)) {
            logger.error("aliPayAppId 或 ali-pay.app.public-key 或 ali-pay.app.private-key 未配置,请检查!");
            throw new ResponseException(ResponseResult.NOT_CONFIG_ALI_PAY);
        }
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId,
                privateKey, "json", "UTF-8", publicKey,
                "RSA2");
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        request.setNotifyUrl(PayUtils.getNotifyUrl(PayWay.ALI_APP_API));
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderInfo.getOrderNum());
        bizContent.put("total_amount", orderInfo.getPayMoney());
        bizContent.put("subject", orderInfo.getOrderName());
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");
        //bizContent.put("time_expire", "2022-08-01 22:00:00");
        //// 商品明细信息,按需传入
        List<JSONObject> goodsDetail = ArrayUtils.newArrayList();
        JSONObject goods = new JSONObject();
        goods.put("goods_id", orderInfo.getOrderId());
        goods.put("goods_name", orderInfo.getOrderName());
        goods.put("quantity", 1);
        goods.put("price", orderInfo.getPayMoney());
        goodsDetail.add(goods);
        bizContent.put("goods_detail", goodsDetail);
        //// 扩展信息,按需传入
        //JSONObject extendParams = new JSONObject();
        //extendParams.put("sys_service_provider_id", "2088511833207846");
        //bizContent.put("extend_params", extendParams);
        request.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        if (response.isSuccess()) {
            return response;
        }
        throw new ResponseException(ResponseResult.PLACE_ORDER_FAILURE);
    }
}

三、支付回调

  • 实现回调代码
package com.flycoding.biz.order.api.notify.ali;

import com.alibaba.fastjson.TypeReference;
import com.alipay.api.internal.util.AlipaySignature;
import com.flycoding.biz.order.api.notify.base.BasePayNotifyExtend;
import com.flycoding.biz.order.config.OrderResponseConfig;
import com.flycoding.biz.order.entity.OrderInfo;
import com.flycoding.biz.order.entity.ali.AliPayNotifyBO;
import com.flycoding.drivenlibrary.engine.annotation.api.Api;
import com.flycoding.drivenlibrary.engine.config.constants.DrivenConstants;
import com.flycoding.drivenlibrary.enums.ResponseResult;
import com.flycoding.drivenlibrary.enums.dictionary.ContentType;
import com.flycoding.drivenlibrary.exception.ResponseException;
import com.flycoding.drivenlibrary.factory.OpenPlatformConfig;
import com.flycoding.utillibrary.strings.StringUtils;

import java.util.Map;

/**
 * 支付宝App支付回调
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/12/9 20:23
 * @Copyright(C): 2022 by 赵屈犇
 */
@Api(apiUrl = "notify", apiName = "支付宝回调", moduleUrl = "pay/aliApp", isVerifyToken = false, isVerifyLogin = false,
        isEncryptedResult = false, isDecryptParams = false, isStartAuth = false,
        responseCode = OrderResponseConfig.ALI_NOTIFY_RESPONSE, requestContentType = ContentType.NOT_VERIFY
)
public class AliAppPayNotifyExtend extends BasePayNotifyExtend<AliPayNotifyBO> {

    @Override
    protected boolean isPaySuccess(OrderInfo orderInfo, OpenPlatformConfig platform) throws Exception {
        AliPayNotifyBO payNotifyBO = getRequestParams();
        String publicKey = platform.getSecretConfig(DrivenConstants.PlatformConstants.AliPayConstants.APP_ALI_PUBLIC_KEY);
        if (StringUtils.isEmpty(publicKey)) {
            logger.error("未定义支付宝公钥,请联系开发者!");
            throw new ResponseException(ResponseResult.NOT_CONFIG_ALI_PAY);
        }
        Map<String, String> params = getParams().toJavaObject(new TypeReference<Map<String, String>>() {});
        return AlipaySignature.rsaCheckV1(params, publicKey, payNotifyBO.getCharset(), payNotifyBO.getSign_type());
    }
}

三、Android功能开发

1、引入jar

// 支付宝支付SDK相关
api 'com.alipay.sdk:alipaysdk-android:+@aar'

2、实现调用函数

/**
 * 调用SDK支付宝支付
 *
 * @param context
 * @param payInfo
 */
public void payAlipay(final Context context, final String payInfo, final String extData) {
    Runnable payRunnable = () -> {
        // 构造PayTask 对象
        PayTask alipay = new PayTask((Activity) context);
        Map<String,String> result = alipay.payV2(payInfo,true);
        result.put("extData", extData);
        Message msg = new Message();
        msg.what = PayConstants.SDK_PAY_FLAG;
        msg.obj = result;
        handler.sendMessage(msg);
    };
    // 必须异步调用
    Thread payThread = new Thread(payRunnable);
    payThread.start();
}