java支付宝电脑网页支付

java支付宝电脑网页支付

官网文档:https://opendocs.alipay.com/open/270/105902
电脑网站支付

1.先给应用申请电脑网页支付功能

在这里插入图片描述

2.根据接口文档 ,请求支付宝接口

文档地址
https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay?scene=API002020081300013629

电脑网站支付需要调用的接口是
alipay.trade.page.pay(统一收单下单并支付页面接口)
在这里插入图片描述

上面图片是调取支付宝接口的公共参数:其中
return_url:是支付成功之后,跳转回原网站的页面地址,注意:(这是支付完成后,支付宝重定向回原网站的页面的url,是公网可以直接访问的地址)。
notify_url:支付宝服务器主动通知商户服务器里指定的页面http/https路径,这个是回调地址,就是支付成功之后,支付宝会通过这个地址(接口)发起请求,这个地址也必须是公网可访问的地址。
biz_content:除了公共请求参数之外,其余的请求参数放到这个里面,

biz_content里面有一个请求参数:
qr_pay_mode:PC 扫码支付的方式,支持前置模式和跳转模式。
		前置模式分为 0,1,3,4
		跳转模式为 2
		前置模式是将二维码前置到商户的订单确认页的模式。需要商户在自己的页面中以 iframe 方式请求支付宝页面。具体分为以下几种:0:订单码-简约前置模式,对应 iframe 宽度不能小于600px,高度不能小于300px;1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于600px;3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于75px;4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小。 跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。2:订单码-跳转模式

我的例子中使用的是跳转模式,如果要试试其他的模式,改一下参数就行,页面效果都不一样。

3.导入sdk,maven依赖

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

4.请求实例

支付宝的请求实例
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setBizContent("{" +
"\"out_trade_no\":\"20150320010101001\"," +
"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
"\"total_amount\":88.88," +
"\"subject\":\"Iphone6 16G\"," +
"\"body\":\"Iphone6 16G\"," +
"\"time_expire\":\"2016-12-31 10:05:01\"," +
"      \"goods_detail\":[{" +
"        \"goods_id\":\"apple-01\"," +
"\"alipay_goods_id\":\"20010001\"," +
"\"goods_name\":\"ipad\"," +
"\"quantity\":1," +
"\"price\":2000," +
"\"goods_category\":\"34543238\"," +
"\"categories_tree\":\"124868003|126232002|126252004\"," +
"\"body\":\"特价手机\"," +
"\"show_url\":\"http://www.alipay.com/xxx.jpg\"" +
"        }]," +
"\"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +
"\"extend_params\":{" +
"\"sys_service_provider_id\":\"2088511833207846\"," +
"\"hb_fq_num\":\"3\"," +
"\"hb_fq_seller_percent\":\"100\"," +
"\"industry_reflux_info\":\"{\\\\\\\"scene_code\\\\\\\":\\\\\\\"metro_tradeorder\\\\\\\",\\\\\\\"channel\\\\\\\":\\\\\\\"xxxx\\\\\\\",\\\\\\\"scene_data\\\\\\\":{\\\\\\\"asset_name\\\\\\\":\\\\\\\"ALIPAY\\\\\\\"}}\"," +
"\"card_type\":\"S0JP0000\"" +
"    }," +
"\"goods_type\":\"0\"," +
"\"timeout_express\":\"90m\"," +
"\"promo_params\":\"{\\\"storeIdType\\\":\\\"1\\\"}\"," +
"\"royalty_info\":{" +
"\"royalty_type\":\"ROYALTY\"," +
"        \"royalty_detail_infos\":[{" +
"          \"serial_no\":1," +
"\"trans_in_type\":\"userId\"," +
"\"batch_no\":\"123\"," +
"\"out_relation_id\":\"20131124001\"," +
"\"trans_out_type\":\"userId\"," +
"\"trans_out\":\"2088101126765726\"," +
"\"trans_in\":\"2088101126708402\"," +
"\"amount\":0.1," +
"\"desc\":\"分账测试1\"," +
"\"amount_percentage\":\"100\"" +
"          }]" +
"    }," +
"\"sub_merchant\":{" +
"\"merchant_id\":\"2088000603999128\"," +
"\"merchant_type\":\"alipay: 支付宝分配的间连商户编号, merchant: 商户端的间连商户编号\"" +
"    }," +
"\"merchant_order_no\":\"20161008001\"," +
"\"enable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," +
"\"store_id\":\"NJ_001\"," +
"\"disable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," +
"\"qr_pay_mode\":\"1\"," +
"\"qrcode_width\":100," +
"\"settle_info\":{" +
"        \"settle_detail_infos\":[{" +
"          \"trans_in_type\":\"cardAliasNo\"," +
"\"trans_in\":\"A0001\"," +
"\"summary_dimension\":\"A0001\"," +
"\"settle_entity_id\":\"2088xxxxx;ST_0001\"," +
"\"settle_entity_type\":\"SecondMerchant、Store\"," +
"\"amount\":0.1" +
"          }]," +
"\"settle_period_time\":\"7d\"" +
"    }," +
"\"invoice_info\":{" +
"\"key_info\":{" +
"\"is_support_invoice\":true," +
"\"invoice_merchant_name\":\"ABC|003\"," +
"\"tax_num\":\"1464888883494\"" +
"      }," +
"\"details\":\"[{\\\"code\\\":\\\"100294400\\\",\\\"name\\\":\\\"服饰\\\",\\\"num\\\":\\\"2\\\",\\\"sumPrice\\\":\\\"200.00\\\",\\\"taxRate\\\":\\\"6%\\\"}]\"" +
"    }," +
"\"agreement_sign_params\":{" +
"\"personal_product_code\":\"GENERAL_WITHHOLDING_P\"," +
"\"sign_scene\":\"INDUSTRY|CARRENTAL\"," +
"\"external_agreement_no\":\"test\"," +
"\"external_logon_id\":\"13852852877\"," +
"\"sign_validity_period\":\"2m\"," +
"\"third_party_type\":\"PARTNER\"," +
"\"buckle_app_id\":\"1001164\"," +
"\"buckle_merchant_id\":\"268820000000414397785\"," +
"\"promo_params\":\"{\\\"key\\\",\\\"value\\\"}\"" +
"    }," +
"\"integration_type\":\"PCWEB\"," +
"\"request_from_url\":\"https://\"," +
"\"business_params\":\"{\\\"data\\\":\\\"123\\\"}\"," +
"\"ext_user_info\":{" +
"\"name\":\"李明\"," +
"\"mobile\":\"16587658765\"," +
"\"cert_type\":\"IDENTITY_CARD\"," +
"\"cert_no\":\"362334768769238881\"," +
"\"min_age\":\"18\"," +
"\"fix_buyer\":\"F\"," +
"\"need_check_info\":\"F\"" +
"    }" +
"  }");
AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
if(response.isSuccess()){
System.out.println("调用成功");
} else {
System.out.println("调用失败");
}

请求参数太多了,我们可能只需要简单的支付功能,
我们后台的请求代码

/**
     * 统一收单下单并支付页面接口
     * @param title 支付名称
     * @param amount 支付金额 (元)
     * @param outTradeNo 商户订单号 (自己生成的,不重复订单号)
     * @return
     * @throws Exception
     */
    public static String pagePaySubmitOrder(String title, String amount, String outTradeNo) {
        String str = null;
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
//        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setBody("fireantPay");
        model.setSubject(title);
//        //商户订单号
        model.setOutTradeNo(outTradeNo);
        //销售产品码,与支付宝签约的产品码名称。注:目前电脑支付场景下仅支持FAST_INSTANT_TRADE_PAY
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
//        //过期时间
        model.setTimeoutExpress("30m");
        //总价
        model.setTotalAmount(amount);
        //商品详情
        GoodsDetail gd1 = new GoodsDetail();
        gd1.setGoodsId("kc-01");
        gd1.setGoodsName(title);
        gd1.setQuantity(1L);
        gd1.setPrice(amount);
        gd1.setBody(title);
        ArrayList<GoodsDetail> goodsDetails = new ArrayList<>();
        goodsDetails.add(gd1);
        model.setGoodsDetail(goodsDetails);
        //PC 扫码支付的方式,支持前置模式和跳转模式。
        //前置模式是将二维码前置到商户的订单确认页的模式。需要商户在自己的页面中以 iframe 方式请求支付宝页面。具体分为以下几种:0:订单码-简约前置模式,对应 iframe 宽度不能小于600px,高度不能小于300px;1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于600px;3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于75px;4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小。
        //跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。2:订单码-跳转模式
        model.setQrPayMode("2");
        //请求参数的集合
        request.setBizModel(model);
        //回调地址
        request.setNotifyUrl(ALiPayConstant.NOTIFY_URL);
        //支付成功 网站跳转地址
        request.setReturnUrl(ALiPayConstant.RETURN_URL);
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
            str = response.getBody();
            log.info("app调用支付宝参数:"+str);
            System.out.println("app调用支付宝参数:"+str);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return str;
    }

5.将返回数据渲染到页面上,

上面方法,返回的是一段html代码,一个form表单和提交这个form表单的js代码。
返回实例

<form name="punchout_form" method="post" action="https://openapi.alipay.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=sign%3D%3D&return_url=https%3A%2F%2Fm.alipay.com%2FGk8NF23&notify_url=https%3A%2F%2Fwww.baidu%2Faaa%2Fp2p%2notify&version=1.0&app_id=2021010101010101&sign_type=RSA2&timestamp=2020-10-28+14%3A00%3A41&alipay_sdk=alipay-sdk-java-4.8.73.ALL&format=json">
<input type="hidden" name="biz_content" value="{&quot;body&quot;:&quot;fireantPay&quot;,&quot;goods_detail&quot;:[{&quot;body&quot;:&quot;认证支付&quot;,&quot;goods_id&quot;:&quot;kc-01&quot;,&quot;goods_name&quot;:&quot;认证支付&quot;,&quot;price&quot;:&quot;0.01&quot;,&quot;quantity&quot;:1}],&quot;out_trade_no&quot;:&quot;BaiDuALi20201028140041468249&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;,&quot;qr_pay_mode&quot;:&quot;2&quot;,&quot;subject&quot;:&quot;认证支付&quot;,&quot;timeout_express&quot;:&quot;30m&quot;,&quot;total_amount&quot;:&quot;0.01&quot;}">
<input type="submit" value="立即支付" style="display:none" >
</form>
<script>document.forms[0].submit();</script>

这段代码渲染到页面上会自动提交这个表单,因为有<script>document.forms[0].submit();</script> 这段js代码。
但是我在使用vue的时候,ajax请求之后,这个表单并没有自动提交,这样的话页面上展示的就是一个空白的界面了,所以需要在渲染页面之后,再次提交表单,加入以下代码即可

setTimeout(()=>{
                  document.forms[0].submit();
        },100)

页面效果
这里我使用的是跳转模式,代码中 设置 :

model.setQrPayMode("2");   

在这里插入图片描述
在这里插入图片描述
支付成功之后,就会根据之前设置好的return_url地址,重定向到那个页面

6.回调接口实例:
在请求参数中设置的notify_url地址,支付成功之后,支付宝会请求这个接口(直接公网能够访问,不要被拦截了),
实例:
controller层:

@RequestMapping(value = "aliPayNotify")
    @ResponseBody
    public String aliPayNotifyInterface(HttpServletRequest request) {
        return payService.aliPayNotifyService(request);
    }

service层:

public String aliPayNotifyService(HttpServletRequest request) {
        //获取支付宝POST过来反馈信息
        System.out.println("支付宝回调-----");
        try {
            Map<String, String> params = new HashMap<>();
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) 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);
            }
                //验证签名
                boolean flag = ALiPayUtil.aliCheckRsa(params);
                if (flag) {
                    String trade_status = params.get("trade_status");
                    //支付成功,插入微型支付记录
                    if (trade_status.equals("TRADE_SUCCESS")) {

                       //支付校验成功,这里进行业务操作

                    }else{
                        System.out.println("支付宝订单-支付状态异常订单:"+JSON.toJSONString(params));
                    }
                    return "success";
                }else{
                    System.out.println("支付宝订单-验证失败订单:"+JSON.toJSONString(params));
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "fail";
    }

注意:支付宝回调接口返回 success,代表请求成功,返回其他的代表请求失败,支付宝会不定期再次请求这个接口(如果成功返回success即可,切勿让支付宝重复请求)。

验证签名方法:ALiPayUtil.aliCheckRsa

/**
     * 异步回调验证接口
     * @param params
     * @return
     * @throws AlipayApiException
     */
    public static boolean aliCheckRsa(Map<String,String> params) throws AlipayApiException {
        //切记ALI_PUBLIC_KEY是支付宝的公钥,请去open.alipay.com对应应用下查看。
        return AlipaySignature.rsaCheckV1(params, ALI_PUBLIC_KEY, "utf-8", "RSA2");
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值