PC网站和uniapp安卓APP、H5接入支付宝支付

发布于:2025-07-12 ⋅ 阅读:(18) ⋅ 点赞:(0)

        首先我们需要完成支付宝账号注册,支持的账号类型:支付宝企业账号支付宝个人账号个体工商户

            到支付宝商家平台 产品中心开通APP支付、手机网站支付、电脑网站支付的产品权限。

            一、电脑PC网站接入

            电脑PC网站支付是指商户在电脑网页展示商品或服务,用户在商户页面确认使用支付宝支付时,浏览器自动跳转支付宝电脑网页完成付款的支付产品。

         签约申请提交材料要求如下:

    • 提供网站地址,网站能正常访问且页面显示完整,网站需要明确经营内容且有完整的商品信息。
    • 网站必须通过 ICP 备案,且备案主体需与支付宝账号主体一致。若网站备案主体与当前账号主体不同时需上传授权函。
    • 如以个人账号申请,需提供营业执照,且支付宝账号名称需与营业执照主体一致。

            1、登录支付宝开放平台创建 网页/移动应用。应用类型选择网页应用,填入应用访问的网站地址。 

       

            2、配置接口加签方式、应用网关,详见接入准备

            需要注意应用网关:用于接收支付宝异步通知消息,需要传入 http(s) 公网地址。不设置的话无法接受异步通知。支付宝网关地址:开发者调用 OpenAPI 发送 http(s) 请求的目标地址,需配置在AlipayClient中。

            3、网页/移动应用:需要手动上线。提交审核后,预计 1 个工作日的审核时间。

            4、绑定商家账号

            在支付宝开放平台创建的应用归属于对应的开放平台账号。如果要在应用中使用支付和资金等相关产品,需要将应用和支付宝商家平台账号绑定,应用才可调用需要商家开通的产品。

            5、集成支付宝SDK

            <dependency>
                <groupId>com.alipay.sdk</groupId>
                <artifactId>alipay-sdk-java</artifactId>
                <version>4.40.308.ALL</version>
            </dependency>

            6、支付配置

            7、接入 统一收单下单并支付页面接口

            可以参考示例代码编写自己的代码:

    package com.ynfy.buss.mall.pay.service.alipay._native.impl;
    
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.domain.AlipayTradePagePayModel;
    import com.alipay.api.request.AlipayTradePagePayRequest;
    import com.alipay.api.response.AlipayTradePagePayResponse;
    import com.ynfy.buss.mall.pay.service.alipay._native.INativePayService;
    import com.ynfy.common.utils.HttpUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.jeecg.common.exception.JeecgBootException;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.math.BigDecimal;
    
    /**
     * 支付宝电脑网站支付
     *
     * @author yangfeng
     * @since 2020/12/21 17:44
     */
    @Slf4j
    @Component
    public class AliNativePayServiceImpl implements INativePayService {
    
        /**
         * app的id
         */
        @Value("${alipay.wapAppId}")
        private String wapAppId;
    
        /**
         * 私钥
         */
        @Value("${alipay.privateKey}")
        public String privateKey;
    
        /**
         * 公钥
         */
        @Value("${alipay.publicKey}")
        public String publicKey;
    
        /**
         * 支付回调地址
         */
        @Value("${alipay.notifyUrl}")
        String notifyUrl;
    
        /**
         * 网关地址
         */
        @Value("${alipay.serverUrl}")
        String serverUrl;
    
    
        @Override
        public Object pay(String orderSn, BigDecimal price, String description) {
            AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, wapAppId, privateKey, "json", "UTF-8", publicKey, "RSA2");
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            model.setBody(description);
            model.setSubject(description);
            model.setOutTradeNo(orderSn);
            model.setProductCode("FAST_INSTANT_TRADE_PAY");
            // 设置PC扫码支付的方式
            model.setQrPayMode("1");
            // 设置请求后页面的集成方式
            model.setIntegrationType("PCWEB");
            model.setTimeoutExpress("30m");
            model.setTotalAmount(price.toString());
            request.setBizModel(model);
            request.setNotifyUrl(notifyUrl);
            try {
                AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");
                return response.getBody();
            } catch (Exception e) {
                throw new JeecgBootException("支付宝电脑网站统一下单接口报错:" + HttpUtils.getErrorMsgFromWxPay(e.getMessage()));
            }
        }
    
    }
    

            8、iframe嵌入上述接口返回的连接,展示在自己的支付页面中。效果如下图:

            用户支付完成后,触发回调通知,根据支付结果更新订单状态。回调接口代码:

     @IgnoreAuth
        @ApiLog(value = "支付宝支付回调")
        @PostMapping("aliPayCallback")
        public Object aliPayCallback() throws Exception {
            log.info("支付宝支付回调通知...");
            //获取支付宝POST过来反馈信息,将异步通知中收到的待验证所有参数都存放到map中
            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] + ",";
                }
                //乱码解决,这段代码在出现乱码时使用。
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
            //调用SDK验证签名
            //公钥验签
            log.info("支付宝支付回调返回参数:{}", params);
            boolean signVerified = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", "RSA2");
            if (signVerified) {
                log.info("支付宝支付验签成功...");
                List<PurchaseOrder> updateOrderList = new ArrayList<>();
                // 验签成功后
                // 获取支付结果参数
                String tradeStatus = request.getParameter("trade_status");
                log.info("支付宝支付回调交易状态:{}", tradeStatus);
                String outTradeNo = request.getParameter("out_trade_no");
                log.info("支付宝支付回调订单号:{}", outTradeNo);
                String gmtPayment = request.getParameter("gmt_payment");
    
                // 根据支付结果参数处理业务逻辑
                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                    // 更新订单状态为支付成功
                    orderService.updateOrderPayCallback(updateOrderList, CommonConstant.PAY_METHOD_ALI, outTradeNo, true, gmtPayment);
                    log.info("支付宝支付回调通知处理完成,共更新{}个订单", updateOrderList.size());
                    return "success";
                } else {
                    // 更新订单状态为支付失败
                    orderService.updateOrderPayCallback(updateOrderList, CommonConstant.PAY_METHOD_ALI, outTradeNo, false, null);
                    return "fail";
                }
            }
            log.info("支付宝支付验签失败...");
            return "fail";
        }

            然后在页面中定时器监听订单状态,通知用户支付是否成功。

            二、uniapp手机网站(H5)接入支付

            手机网站支付是指商家在移动端网页展示商品或服务,用户在商家页面确认使用支付宝支付后,浏览器自动跳转支付宝 App 或支付宝网页完成付款的支付产品。

            1、登录支付宝开放平台创建 网页/移动应用,这里的应用类型也是网页应用,可以和上面的PC网页应用共享,所以不用再创建。

            2、接入 手机网站支付接口2.0

            可以参考示例代码编写自己的代码:

    package com.ynfy.buss.mall.pay.service.alipay.h5.impl;
    
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.domain.AlipayTradeWapPayModel;
    import com.alipay.api.request.AlipayTradeWapPayRequest;
    import com.alipay.api.response.AlipayTradeWapPayResponse;
    import com.ynfy.buss.mall.pay.service.alipay.h5.IH5PayService;
    import com.ynfy.common.utils.HttpUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.jeecg.common.exception.JeecgBootException;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.math.BigDecimal;
    
    /**
     * 支付宝H5支付
     *
     * @author yangfeng
     * @since 2020/12/21 17:44
     */
    @Slf4j
    @Component
    public class AliH5PayServiceImpl implements IH5PayService {
    
        /**
         * app的id
         */
        @Value("${alipay.wapAppId}")
        private String wapAppId;
    
        /**
         * 私钥
         */
        @Value("${alipay.privateKey}")
        public String privateKey;
    
        /**
         * 公钥
         */
        @Value("${alipay.publicKey}")
        public String publicKey;
    
        /**
         * 支付回调地址
         */
        @Value("${alipay.notifyUrl}")
        String notifyUrl;
    
        /**
         * 网关地址
         */
        @Value("${alipay.serverUrl}")
        String serverUrl;
    
        @Override
        public Object pay(String orderSn, BigDecimal price, String description) {
            AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, wapAppId, privateKey, "json", "UTF-8", publicKey, "RSA2");
            // 构造请求参数以调用接口
            AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
            AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
            model.setSubject(description);
            model.setOutTradeNo(orderSn);
            // 设置产品码
            model.setProductCode("QUICK_WAP_WAY");
            model.setTimeoutExpress("30m");
            model.setTotalAmount(price.toString());
            request.setBizModel(model);
            request.setNotifyUrl(notifyUrl);
            try {
                AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "GET");
                return response.getBody();
            } catch (Exception e) {
                throw new JeecgBootException("支付宝h5统一下单接口报错:" + HttpUtils.getErrorMsgFromWxPay(e.getMessage()));
            }
        }
    
    }
    

                   3、uniapp调用上述支付接口,跳转返回的链接页面代码:

    
    /**
     * 支付
     * @param response
     */
    export function payment(response, clientType) {
    	//app端需要判断操作系统是否为华为鸿蒙
    	// #ifdef APP-PLUS
    	if (isHarmonyOS()) {
    		uni.showToast({
    			icon: "none",
    			title: "鸿蒙暂不可支付",
    		});
    		return
    	}
    	// #endif
    
    	const provider = clientType == 'WxPay' ? "wxpay" : clientType == 'AliPay' ? 'alipay' : '';
    	if (!provider) {
    		uni.showToast({
    			icon: "none",
    			title: "支付方式缺失",
    		});
    		return
    	}
    	//app微信支付 orderInfo为json对象
    	//app支付宝支付 orderInfo为字符串,https://uniapp.dcloud.net.cn/tutorial/app-payment-alipay.html
    	let orderInfo = null;
    	if (provider == "wxpay") {
    		orderInfo = {
    			appid: response.appid,
    			noncestr: response.nonceStr,
    			package: response.packageVal,
    			partnerid: response.partnerId,
    			prepayid: response.prepayId,
    			timestamp: response.timestamp,
    			sign: response.sign
    		}
    	} else if (provider == "alipay") {
    		orderInfo = response
    	}
    	uni.requestPayment({
    		provider: provider,
    		// #ifdef APP-PLUS
    		orderInfo: orderInfo,
    		// #endif
    		// #ifdef MP-WEIXIN
    		timeStamp: response.timeStamp,
    		nonceStr: response.nonceStr,
    		package: response.packageVal,
    		signType: response.signType,
    		paySign: response.paySign,
    		// #endif
    		success: (e) => {
    			uni.showToast({
    				icon: "none",
    				title: "支付成功!",
    			});
    			setTimeout(() => {
    				uni.navigateTo({
    					url: "/subpages/myorder/myorder"
    				})
    			}, 1000)
    		},
    		fail: (e) => {
    			uni.showModal({
    				title: "支付失败",
    				content: "如果您已支付,请勿反复支付",
    				showCancel: false,
    				success: () => {
    					uni.redirectTo({
    						url: "/subpages/myorder/myorder?orderStatus=0",
    					});
    				},
    			});
    		},
    	});
    }
    
    export function isHarmonyOS() {
    	const sysInfo = uni.getSystemInfoSync();
    	// 检查版本号是否包含"HarmonyOS"或"10+"等标识
    	return /(10\+|\+HarmonyOS)/.test(sysInfo.system);
    }
    
    // 去支付
    export async function goPay(orderSn, clientType) {
    	const orderData = await apiGetOrder(orderSn);
    	const payParams = {
    		clientType: clientType,
    		// #ifdef MP-WEIXIN
    		paymentType: "MP",
    		// #endif
    		// #ifdef H5
    		paymentType: "H5",
    		// #endif
    		// #ifdef APP-PLUS
    		paymentType: "APP",
    		// #endif
    		price: orderData.orderPrice,
    		orderSn: orderSn,
    		description: orderData.orderTitle
    	};
    	const response = await apiPay(payParams);
    	// #ifdef MP-WEIXIN || APP-PLUS
    	payment(response, clientType)
    	// #endif
    	// #ifdef H5
    	if (clientType == 'WxPay') {
    		window.location.href = response.h5Url
    	} else if (clientType == 'AliPay') {
    		window.location.href = response
    	}
    	// #endif
    }

             4、打开支付宝APP完成付款。效果如下:

            三、uniapp安卓 APP支付

            APP支付是指商家在商家移动端 App 中集成支付宝 SDK,调起支付宝来完成付款的一种支付产品。适用于在商家移动端 App 内使用支付宝支付功能的场景。

         签约申请提交材料要求如下:

    • 如应用已上架,需提供应用名称和已上架的应用市场;若应用未上架,需提供 Demo 或产品说明文档。
    • 应用必须包含明确的经营内容和价格信息;且经营内容须与营业执照经营范围一致。
    • 如应用开发者与支付宝账号名称不一致需提供开发者授权函。
    • 个人账号申请,需提供营业执照,且支付宝账号名称需与营业执照主体一致。

            1、登录 支付宝开放平台,点击创建 网页/移动应用。(仅支持应用类型为 移动应用 接入)。

         2、配置接口加签方式、应用网关,详见接入准备。 

            3、网页/移动应用:需要手动上线。提交审核后,预计 1 个工作日的审核时间。

            4、绑定商家账号

            在支付宝开放平台创建的应用归属于对应的开放平台账号。如果要在应用中使用支付和资金等相关产品,需要将应用和支付宝商家平台账号绑定,应用才可调用需要商家开通的产品。

            5、接入 app支付接口2.0

            可以参考示例代码编写自己的代码:

    package com.ynfy.buss.mall.pay.service.alipay.app.impl;
    
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.domain.AlipayTradeAppPayModel;
    import com.alipay.api.request.AlipayTradeAppPayRequest;
    import com.alipay.api.response.AlipayTradeAppPayResponse;
    import com.ynfy.buss.mall.pay.service.alipay.app.IAppPayService;
    import com.ynfy.common.utils.HttpUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.jeecg.common.exception.JeecgBootException;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.math.BigDecimal;
    
    /**
     * 支付宝APP支付
     *
     * @author yangfeng
     * @since 2020/12/21 17:44
     */
    @Slf4j
    @Component
    public class AliAppPayServiceImpl implements IAppPayService {
    
        /**
         * app的id
         */
        @Value("${alipay.appAppId}")
        private String appId;
    
        /**
         * 私钥
         */
        @Value("${alipay.privateKey}")
        public String privateKey;
    
        /**
         * 公钥
         */
        @Value("${alipay.publicKey}")
        public String publicKey;
    
        /**
         * 支付回调地址
         */
        @Value("${alipay.notifyUrl}")
        String notifyUrl;
    
        /**
         * 网关地址
         */
        @Value("${alipay.serverUrl}")
        String serverUrl;
    
    
        @Override
        public Object pay(String orderSn, BigDecimal price, String description) {
            AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, "json", "UTF-8", publicKey, "RSA2");
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setSubject(description);
            model.setOutTradeNo(orderSn);
            // 设置产品码
            model.setProductCode("QUICK_MSECURITY_PAY");
            model.setTimeoutExpress("30m");
            model.setTotalAmount(price.toString());
            request.setBizModel(model);
            request.setNotifyUrl(notifyUrl);
            try {
                //这里和普通的接口调用不同,使用的是sdkExecute
                AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
                return response.getBody();
            } catch (Exception e) {
                throw new JeecgBootException("支付宝APP统一下单接口报错:" + HttpUtils.getErrorMsgFromWxPay(e.getMessage()));
            }
        }
    
    }
    

             6、uniapp调用上述接口,调起支付宝支付控件。效果如图:


    网站公告

    今日签到

    点亮在社区的每一天
    去签到