Java: Alipay pay demo (public key certificate method)-sandbox environment test version

1. After downloading the demo paid in person on the Alipay open platform, modify the Alipay SDK version to 4.11.21.ALL or the latest version (the 3.3.0 version of the demo does not support the certificate method)

<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.11.21.ALL</version>
</dependency>
 

2. Import the bcprov-jdk*.jar package, otherwise an error will be reported: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider

<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>

3. Modify zfbinfo.properties (in the formal environment, these three certificates should be stored separately in another folder, not packaged into a jar)


# 支付宝网关名、partnerId和appId
open_api_domain = https://openapi.alipaydev.com/gateway.do
mcloud_api_domain = http://mcloudmonitor.com/gateway.do
#商户UID
pid = 20***913  
appid = 2***565 
# 应用私钥
private_key = MII****SkAgE
# 应用公钥证书 绝对地址
certPath = E:/****/CSR/appCertPublicKey_2021000117600565.crt

# 支付宝根证书 绝对地址
rootCertPath = E:/****/CSR/alipayRootCert.crt

#SHA256withRsa对应支付宝公钥证书   绝对地址
alipayPublicCertPath = E:/****/CSR/alipayCertPublicKey_RSA2.crt
# 签名类型: RSA->SHA1withRsa,RSA2->SHA256withRsa
sign_type = RSA2

4. Coding

package com.alipay.demo.trade;

import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.TradeFundBill;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.MonitorHeartbeatSynResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.*;
import com.alipay.demo.trade.model.hb.*;
import com.alipay.demo.trade.model.result.AlipayF2FPayResult;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult;
import com.alipay.demo.trade.service.AlipayMonitorService;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayMonitorServiceImpl;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.alipay.demo.trade.service.impl.AlipayTradeWithHBServiceImpl;
import com.alipay.demo.trade.utils.Utils;
import com.alipay.demo.trade.utils.ZxingUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

/**
 * Created by liuyangkly on 15/8/9.
 * 简单main函数,用于测试当面付api
 * sdk和demo的意见和问题反馈请联系:[email protected]
 */
public class Main {
    private static Log                  log = LogFactory.getLog(Main.class);

    // 支付宝当面付2.0服务
    private static AlipayTradeService   tradeService;

    // 支付宝当面付2.0服务(集成了交易保障接口逻辑)
    private static AlipayTradeService   tradeWithHBService;

    // 支付宝交易保障接口服务,供测试接口api使用,请先阅读readme.txt
    private static AlipayMonitorService monitorService;

    private static final String certPath;
    private static final String rootCertPath;
    private static final String alipayPublicCertPath;

    static {
        /** 一定要在创建AlipayTradeService之前调用Configs.init()设置默认参数
         *  Configs会读取classpath下的zfbinfo.properties文件配置信息,如果找不到该文件则确认该文件是否在classpath目录
         */
        Configs.init("zfbinfo.properties");
        ResourceBundle rb = ResourceBundle.getBundle("zfbinfo"); //没有.properties结尾
        certPath = rb.getString("certPath");
        rootCertPath = rb.getString("rootCertPath");
        alipayPublicCertPath = rb.getString("alipayPublicCertPath");
    }

    // 简单打印应答
    private void dumpResponse(AlipayResponse response) {
        if (response != null) {
            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
            if (StringUtils.isNotEmpty(response.getSubCode())) {
                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
                    response.getSubMsg()));
            }
            log.info("body:" + response.getBody());
        }
    }

    public static void main(String[] args) throws AlipayApiException {
        Main main = new Main();
        
        // 测试当面付2.0生成支付二维码
        main.test_trade_precreate();
    }

    // 测试当面付2.0生成支付二维码
    public void test_trade_precreate() throws AlipayApiException {
        // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,
        // 需保证商户系统端不能重复,建议通过数据库sequence生成,
        String outTradeNo = "tradeprecreate" + System.currentTimeMillis()
                            + (long) (Math.random() * 10000000L);

        // (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
        String subject = "xxx品牌xxx门店当面付扫码消费";

        // (必填) 订单总金额,单位为元,不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        String totalAmount = "100";

        // (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0";

        // 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号)
        // 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID
        String sellerId = "208***913";

        // 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
        String body = "购买商品3件共20.00元";

        // 商户操作员编号,添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("208***3913");

        // 支付超时,定义为30分钟
        String timeoutExpress = "30m";

        // 商品明细列表,需填写购买商品详细信息,
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
        // 创建一个商品信息,参数含义分别为商品id(使用国标)、名称、单价(单位为分)、数量,如果需要添加商品类别,详见GoodsDetail
        GoodsDetail goods1 = GoodsDetail.newInstance("goods_id001", "xxx小面包", 1000, 1);
        // 创建好一个商品后添加至商品明细列表
        goodsDetailList.add(goods1);

        // 继续创建并添加第一条商品信息,用户购买的产品为“黑人牙刷”,单价为5.00元,购买了两件
        GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "xxx牙刷", 500, 2);
        goodsDetailList.add(goods2);

        // 创建扫码支付请求builder,设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
            .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
            .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
            .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
            .setTimeoutExpress(timeoutExpress)
//                            .setNotifyUrl("http://www.baidu.com")//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
            .setGoodsDetailList(goodsDetailList);
//        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(Configs.getOpenApiDomain());
        certAlipayRequest.setAppId(Configs.getAppid());
        certAlipayRequest.setPrivateKey(Configs.getPrivateKey());
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset("utf-8");
        certAlipayRequest.setSignType(Configs.getSignType());
        certAlipayRequest.setCertPath(certPath);
        certAlipayRequest.setAlipayPublicCertPath(alipayPublicCertPath);
        certAlipayRequest.setRootCertPath(rootCertPath);

        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
        //构造API请求
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
//        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        System.out.println(builder.toJsonString());
        System.out.println(builder.toString());
        request.setBizContent(builder.toJsonString()+"product_code:FACE_TO_FACE_PAYMENT");

        //发送请求
        AlipayTradePrecreateResponse response = alipayClient.certificateExecute(request);
        dumpResponse(response);

        // 需要修改为运行机器上的路径
        String filePath = String.format("C:/Users/***/Desktop/qr-%s.png",
                response.getOutTradeNo());
        log.info("filePath:" + filePath);
//        生成并输出支付二维码
        ZxingUtils.getQRCodeImge(response.getQrCode(), 256, filePath);
    }
}

Different payment methods need to call different methods when constructing API request and sending request 

Pay in person (barcode payment) AlipayTradePayRequest & AlipayTradePayResponse
Pay in person (offline scan code payment) AlipayTradePrecreateRequest&AlipayTradePrecreateResponse
For the time being AlipayTradeCreateRequest&AlipayTradeCreateResponse
APP payment AlipayTradeAppPayRequest & AlipayTradeAppPayResponse
Mobile web payment  AlipayTradeWapPayRequest& AlipayTradeWapPayResponse
Computer web payment AlipayTradePagePayRequest& AlipayTradePagePayResponse

 

 

Guess you like

Origin blog.csdn.net/weixin_38676276/article/details/112788399