精华内容
下载资源
问答
  • 主要介绍了springboot对接支付宝支付接口(详细开发步骤总结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 现如今,手机支付已相当普遍,而作为开发人员应该对手机支付操作有所了解。而支付宝接口是支付宝提供的一个接口,用来对接软件应用程序在进行金钱交易使用。然后对于编程爱好者而言,想学习这一点就有点难,因为要想...
  • 企业级发卡网(已对接支付宝当面付)
  • 商户对接 支付宝支付

    2019-02-21 17:59:31
    商户对接 支付宝支付 源码更容易查看 理解!
  • h5牛欢喜完整版源码+对接免公众+对接支付+搭建文本教程
  • java C# PHP 支付宝微信支付api接口 以及详细接口文档和demo
  • destoon对接支付宝支付,介绍了destoon如何对接支付宝支付功能,从支付宝企业号申请到网站支付成功,亲测成功
  • javaWeb对接支付宝 以及 连连支付 两家第三方支付网站
  • 我已经在线上测试成功了,里边有PHP和App对接支付宝的代码,签名,回调,注意事项
  • 主要介绍了Python对接支付宝支付自实现功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • java对接支付宝功能

    2021-02-21 15:29:59
    java对接支付宝
  • 现在就来实现Django对接支付宝支付功能吧! 登录支付宝开放平台 点击进入蚂蚁金服开放平台https://open.alipay.com/platform/home.htm 进入支付宝沙箱环境...
  • golang对接支付宝支付

    千次阅读 2020-07-31 22:28:58
    沙箱环境 文档:https://docs.open.alipay.com/200/105311/ 沙箱地址:... 密钥(文档已经很详细了,附链接) ... 代码使用的第三方库 ...网页支付 package pays import ..
    1. 沙箱环境

      文档:https://docs.open.alipay.com/200/105311/
      沙箱地址:https://openhome.alipay.com/platform/appDaily.htm

    2. 密钥(文档已经很详细了,附链接)

      https://opendocs.alipay.com/open/291/105971#Krqvg

    3. 代码使用的第三方库

      github.com/smartwalle/alipay/v3

    4. 代码简单实现

    网页支付

      ```go
      package pays
      
      import (
      	"errors"
      	"fmt"
      	"github.com/smartwalle/alipay/v3"
      )
      
      var (
      	// appId
      	appId = ""
      	// 应用公钥
      	aliPublicKey = ""
      	// 应用私钥
      	privateKey = ""
      	client, _  = alipay.New(appId, privateKey, true)
      )
      
      func init() {
      	client.LoadAppPublicCertFromFile("appCertPublicKey.crt")       // 加载应用公钥证书
      	client.LoadAliPayRootCertFromFile("alipayRootCert.crt")        // 加载支付宝根证书
      	client.LoadAliPayPublicCertFromFile("alipayCertPublicKey.crt") // 加载支付宝公钥证书
      }
      
      //手机客户端支付
      func WapAlipay() {
      	var p = alipay.TradeWapPay{}
      	p.NotifyURL = ""
      	p.ReturnURL = "http://xxx"
      	p.Subject = ""
      	p.OutTradeNo = ""
      	p.TotalAmount = ""
      	p.ProductCode = ""
      
      	url, err := client.TradeWapPay(p)
      	if err != nil {
      		fmt.Println("pay client.TradeAppPay error:", err)
      		return
      	}
      
      	//logging.Info(url)
      	binary, _ := url.MarshalBinary()
      	fmt.Println(string(binary))
      }
      
      //转账
      func Alipayout(outBizNo, payeeAccount, amount, payeeRealName string) error {
      
      	var p = alipay.FundTransToAccountTransfer{}
      	p.OutBizNo = outBizNo           // 必选 商户转账唯一订单号
      	p.PayeeType = "ALIPAY_LOGONID"  // 必选 收款方账户类型,"ALIPAY_LOGONID":支付宝帐号
      	p.PayeeAccount = payeeAccount   // 必选 收款方账户。与payee_type配合使用
      	p.Amount = amount               // 必选 转账金额,元
      	p.PayeeRealName = payeeRealName //收款方真实姓名
      	rsp, err := client.FundTransToAccountTransfer(p)
      	if err != nil {
      		fmt.Println("FundTransToAccountTransfer error:", err)
      		return err
      	}
      	if rsp.Content.Code != alipay.CodeSuccess {
      		fmt.Println(rsp.Content.Msg, rsp.Content.SubMsg)
      		return errors.New("pay error:" + rsp.Content.Msg)
      	}
      	fmt.Println(rsp.Content.Msg)
      	return nil
      }
      ```
    
    展开全文
  • 网站对接支付宝即时到账接口步骤 1:必须由公司去支付宝申请签约(申请地址:https://b.alipay.com/order/productDetail.htm?productId=2015110218012942); 2:申请好后就可以获取到PID(以2088开头的16位纯数字...
  • } /** * 支付成功后的支付宝异步通知 */ @RequestMapping(value="/alipay") public String alipay(HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("支付成功后的支付宝...

    步骤:

    第一步:准备支付宝相关的参数,如appId、公私钥

    第二步:写代码,搞起

    第一步:

    1.你需要登录支付宝https://open.alipay.com/platform/developerIndex.htm。

    2.点击控制台—>研发服务
    在这里插入图片描述
    3.到这个地址上生成一对公私钥:https://miniu.alipay.com/keytool/create
    在这里插入图片描述
    4.私钥保存下来,是要放在项目配置里面的,公钥是下面的步骤要用到的。
    5.复制上面的公钥,放到这个输入框里面在这里插入图片描述
    6.保存设置后,打开就可以看到这样的窗口,下面的【敲黑板了!!!支付宝公钥】是放在代码里面的,自己保存下来。
    在这里插入图片描述
    7.点击左边的【沙箱账号】,把账号密码保存下来,支付的时候要用到。
    在这里插入图片描述
    8.到了这一步,咱们所需要的配置基本上就准备齐了

    请看配置
    # 应用ID,您的APPID
    alipay.appId=2021xxxx
    # 支付宝公私钥生成地址:https://miniu.alipay.com/keytool/create
    # 商户私钥,您的PKCS8格式RSA2私钥
    alipay.merchantPrivateKey=第一次生成的私钥
    # 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm
    alipay.alipayPublicKey=支付宝公钥
    # 页面跳转异步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    alipay.notifyUrl=http://5ktbak.natappfree.cc/payment/alipay
    # 页面跳转同步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    alipay.returnUrl=http://5ktbak.natappfree.cc/alipayResult
    
    # 签名方式
    alipay.signType=RSA2
    # 字符编码格式
    alipay.charset=utf-8
    # 支付宝网关
    alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
    

    第二步

    alipay.properties
    # 应用ID,您的APPID
    alipay.appId=2021xxxx
    # 支付宝公私钥生成地址:https://miniu.alipay.com/keytool/create
    # 商户私钥,您的PKCS8格式RSA2私钥
    alipay.merchantPrivateKey=第一次生成的私钥
    # 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm
    alipay.alipayPublicKey=支付宝公钥
    # 页面跳转异步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    alipay.notifyUrl=http://5ktbak.natappfree.cc/payment/alipay
    # 页面跳转同步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    alipay.returnUrl=http://5ktbak.natappfree.cc/alipayResult
    
    # 签名方式
    alipay.signType=RSA2
    # 字符编码格式
    alipay.charset=utf-8
    # 支付宝网关
    alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
    
    AliPayResource.java
    package com.alipay.resource;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    
    @Data
    @Component
    @ConfigurationProperties(prefix="alipay")
    @PropertySource("classpath:alipay.properties")
    public class AliPayResource {
    
        private String appId;
        private String merchantPrivateKey;
        private String alipayPublicKey;
    
        private String notifyUrl;
        private String returnUrl;
    
        private String signType;
        private String charset;
        private String gatewayUrl;
    }
    
    AlipayController.java
    package com.alipay.controller;
    
    import com.alipay.api.AlipayApiException;
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.internal.util.AlipaySignature;
    import com.alipay.api.request.AlipayTradePagePayRequest;
    import com.alipay.resource.AliPayResource;
    import com.alipay.utils.DateUtil;
    import com.alipay.utils.JsonResult;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    /**
     * @author: HuGoldWater
     * @description:
     */
    @Slf4j
    @RestController
    @RequestMapping("payment")
    public class AlipayController {
    
        @Autowired
        private AliPayResource aliPayResource;
    
        /**
         * 前往支付宝进行支付
         */
        @GetMapping(value="/goAlipay")
        public JsonResult goAlipay(String merchantUserId, String merchantOrderId) throws Exception{
            //获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(aliPayResource.getGatewayUrl(),
                    aliPayResource.getAppId(),
                    aliPayResource.getMerchantPrivateKey(),
                    "json",
                    aliPayResource.getCharset(),
                    aliPayResource.getAlipayPublicKey(),
                    aliPayResource.getSignType());
    
            //设置请求参数
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            alipayRequest.setReturnUrl(aliPayResource.getReturnUrl());
            alipayRequest.setNotifyUrl(aliPayResource.getNotifyUrl());
    
            // 商户订单号, 商户网站订单系统中唯一订单号, 必填
            String out_trade_no = merchantOrderId;
            // 付款金额, 必填 单位元
           String total_amount = "0.01";  // 测试用 1分钱
            // 订单名称, 必填
            String subject = "胡金水-付款用户[" + merchantUserId + "]";
            // 商品描述, 可空, 目前先用订单名称
            String body = subject;
    
            // 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
            String timeout_express = "1h";
            alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                    + "\"total_amount\":\""+ total_amount +"\","
                    + "\"subject\":\""+ subject +"\","
                    + "\"body\":\""+ body +"\","
                    + "\"timeout_express\":\""+ timeout_express +"\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
    
            //请求
            String alipayForm = "";
            try {
                alipayForm = alipayClient.pageExecute(alipayRequest).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            log.info("支付宝支付 - 前往支付页面, alipayForm: \n{}", alipayForm);
            return JsonResult.ok(alipayForm);
        }
    
    
        /**
         * 支付成功后的支付宝异步通知
         */
        @RequestMapping(value="/alipay")
        public String alipay(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
            log.info("支付成功后的支付宝异步通知");
    
            //获取支付宝POST过来反馈信息
            Map<String,String> params = new HashMap<String,String>();
            Map<String,String[]> requestParams = request.getParameterMap();
            for (Iterator<String> 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 signVerified = AlipaySignature.rsaCheckV1(params,
                    aliPayResource.getAlipayPublicKey(),
                    aliPayResource.getCharset(),
                    aliPayResource.getSignType()); //调用SDK验证签名
    
            if(signVerified) {//验证成功
                // 商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
                // 支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
                // 交易状态
                String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
                // 付款金额
                String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
    
                if (trade_status.equals("TRADE_SUCCESS")){
    //                String merchantReturnUrl = paymentOrderService.updateOrderPaid(out_trade_no, CurrencyUtils.getYuan2Fen(total_amount));
    //                notifyFoodieShop(out_trade_no,merchantReturnUrl);
                }
    
                log.info("************* 支付成功(支付宝异步通知) - 时间: {} *************", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
                log.info("* 订单号: {}", out_trade_no);
                log.info("* 支付宝交易号: {}", trade_no);
                log.info("* 实付金额: {}", total_amount);
                log.info("* 交易状态: {}", trade_status);
                log.info("*****************************************************************************");
    
                return "success";
            }else {
                //验证失败
                log.info("验签失败, 时间: {}", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
                return "fail";
            }
        }
    
    }
    
    Application.java
    package com.alipay;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class Application {
       public static void main(String[] args) {
          SpringApplication.run(Application.class, args);
       }
    
    }
    

    运行Application,在页面输入localhost:9090/payment/goAlipay?merchantUserId=123456&merchantOrderId=654321

    结果如下:

    五月 08, 2021 11:30:51 下午 org.apache.catalina.core.ApplicationContext log
    信息: Initializing Spring DispatcherServlet 'dispatcherServlet'
    INFO  DispatcherServlet:525 - Initializing Servlet 'dispatcherServlet'
    INFO  DispatcherServlet:547 - Completed initialization in 3 ms
    INFO  AlipayController:80 - 支付宝支付 - 前往支付页面, alipayForm: 
    <form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=0G7TbOfYZn8BS1dYY%2FITfZLBHgz%2F0uBz3XU4ndiw%2Fpd%2BADurlNMtYNugvZpGTjrL4JBJb%2Fgzl6vG%2B9urFCbeLiVDXhnGMIvqzXOY67YVGIMfIDxR%2BOytOzZ3zctPeEVHDZBAjRNy4aOqW1elJ491Q%2BptPNT2X3vy8Qts0Ago1HaOyoCRlFag5nB3fwD5t3NQz4ZCEG8slwERixJnN2sIQLj4NGI2bM2T6x8ayDtehRC89hwXJ1ZY9IyLVkwhby%2BW4HU2LiQ%2BqD%2FOKLmxsC65M5pWNF7vw9uswmEuN5qBswJ5rqlTl6iyYd5EKK2Xqhj6hCQYz0IMR1cymRhqDoPG1Q%3D%3D&return_url=http%3A%2F%2F5ktbak.natappfree.cc%2FalipayResult&notify_url=http%3A%2F%2F5ktbak.natappfree.cc%2Fpayment%2Falipay&version=1.0&app_id=2021000117651511&sign_type=RSA2&timestamp=2021-05-08+23%3A30%3A51&alipay_sdk=alipay-sdk-java-3.7.110.ALL&format=json">
    <input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;654321&quot;,&quot;total_amount&quot;:&quot;0.01&quot;,&quot;subject&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;body&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;timeout_express&quot;:&quot;1h&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;}">
    <input type="submit" value="立即支付" style="display:none" >
    </form>
    <script>document.forms[0].submit();</script>
    

    把上面的html代码放到html文件中:

    <form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=0G7TbOfYZn8BS1dYY%2FITfZLBHgz%2F0uBz3XU4ndiw%2Fpd%2BADurlNMtYNugvZpGTjrL4JBJb%2Fgzl6vG%2B9urFCbeLiVDXhnGMIvqzXOY67YVGIMfIDxR%2BOytOzZ3zctPeEVHDZBAjRNy4aOqW1elJ491Q%2BptPNT2X3vy8Qts0Ago1HaOyoCRlFag5nB3fwD5t3NQz4ZCEG8slwERixJnN2sIQLj4NGI2bM2T6x8ayDtehRC89hwXJ1ZY9IyLVkwhby%2BW4HU2LiQ%2BqD%2FOKLmxsC65M5pWNF7vw9uswmEuN5qBswJ5rqlTl6iyYd5EKK2Xqhj6hCQYz0IMR1cymRhqDoPG1Q%3D%3D&return_url=http%3A%2F%2F5ktbak.natappfree.cc%2FalipayResult&notify_url=http%3A%2F%2F5ktbak.natappfree.cc%2Fpayment%2Falipay&version=1.0&app_id=2021000117651511&sign_type=RSA2&timestamp=2021-05-08+23%3A30%3A51&alipay_sdk=alipay-sdk-java-3.7.110.ALL&format=json">
        <input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;654321&quot;,&quot;total_amount&quot;:&quot;0.01&quot;,&quot;subject&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;body&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;timeout_express&quot;:&quot;1h&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;}">
        <input type="submit" value="立即支付" style="display:none" >
    </form>
    <script>document.forms[0].submit();</script>
    

    打开html文件后,会进入这个页面:
    在这里插入图片描述
    输入沙箱的账号密码:

    在这里插入图片描述
    在这里插入图片描述
    输入密码后,就已经付款完成了,控制台会打印支付成功的回调通知。

    INFO  AlipayController:91 - 支付成功后的支付宝异步通知
    INFO  AlipayController:129 - ************* 支付成功(支付宝异步通知) - 时间: 2021-05-09 00:09:32 *************
    INFO  AlipayController:130 - * 订单号: 123123123123
    INFO  AlipayController:131 - * 支付宝交易号: 2021050922001489970501658602
    INFO  AlipayController:132 - * 实付金额: 0.01
    INFO  AlipayController:133 - * 交易状态: TRADE_SUCCESS
    INFO  AlipayController:134 - *****************************************************************************
    

    如何让支付宝将付款成功的通知,回调到你本机,我使用的是内网穿透:Natapp,可以看到另一篇文章:https://blog.csdn.net/qq_17555933/article/details/116549415

    展开全文
  • App+H5支付方式(比微信简单) 1.登录支付宝开放平台,选择网页和移动应用: 2.填完app相关的信息后,点击App,设置接口加签方式:如下,选择SHA256,然后通过支付宝提供的工具生成公私钥对 3.支付能力选择这...

    App+H5支付方式(比微信简单)

    1.登录支付宝开放平台,选择网页和移动应用:

    2.填完app相关的信息后,点击App,设置接口加签方式:如下,选择SHA256,然后通过支付宝提供的工具生成公私钥对

    3.支付能力选择这两个即可(也可以审核通过再添加):

    4.完成并提交到审核,等审核通过就可以使用了。拿到Appid,公私钥信息,以下是Java的部分代码:仅供参考

    App支付

    //App支付    
    public static String alipay(String outTradeNo,String organId, String totalAmount,String subject,String body) throws Exception{
            AliPayCommonConfig alipayConfig = new AliPayCommonConfig();
            //获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getApp_id(),
            		alipayConfig.getMerchant_private_key(), "json", alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(),
            		alipayConfig.getSign_type());
    
            //QUICK_MSECURITY_PAY
            //该笔订单允许的最晚付款时间
            String timeout= "30m";
            AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setBody(body);
            model.setSubject(subject);
            model.setOutTradeNo(outTradeNo);
            model.setTimeoutExpress(timeout);
            model.setTotalAmount(totalAmount);
            model.setProductCode(alipayConfig.getProductCode_APP());
            ali_request.setBizModel(model);
            
            ali_request.setReturnUrl(alipayConfig.getReturn_url());
            ali_request.setNotifyUrl(alipayConfig.getNotify_url());
         
            //请求
            return alipayClient.sdkExecute(ali_request).getBody();
        }

    H5支付

        //支付宝H5支付
        public static String alipayH5(String outTradeNo,String organId, String totalAmount,String subject,String body) throws Exception{
        	//获得初始化的AlipayClient
            AliPayCommonConfig alipayConfig = new AliPayCommonConfig ();
        	AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getApp_id(),
                    alipayConfig.getMerchant_private_key(), "json", alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(),
                    alipayConfig.getSign_type());
        	
        	//该笔订单允许的最晚付款时间
        	String timeout= "30m";
        	//设置请求参数
        	String content = "{\"out_trade_no\":\""+ outTradeNo +"\"," 
        			+ "\"total_amount\":\""+ totalAmount +"\"," 
        			+ "\"subject\":\""+ subject +"\"," 
        			+ "\"timeout_express\":\""+ timeout +"\"," 
        			+ "\"body\":\""+ body +"\"," 
        			+ "\"product_code\":\""+alipayConfig.getProductCode()+"\"}";
        	AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        	alipayRequest.setReturnUrl(alipayConfig.getReturn_url());
        	alipayRequest.setNotifyUrl(alipayConfig.getNotify_url());
        	alipayRequest.setBizContent(content);                                                                                                                                                               
        	
        	//请求
        	return alipayClient.pageExecute(alipayRequest).getBody();
        }

    5.配置部分:

    //配置部分
    public class AliPayCommonConfig {
    
      // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    	public static String app_id = "";//appid 一般16位数字
    
      // 商户私钥,您的PKCS8格式RSA2私钥
      public static String merchant_private_key = "";
    
      // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
      public static String alipay_public_key = "";
    
      // 服务器异步通知页面路径  需http://AlipayConfig,不能加?id=123这类自定义参数,必须外网可以正常访问 post
      public static String notify_url = "";
    
      // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,沙箱环境下可以填写本地地址 get
      public static String return_url = "";
    
      // 签名方式
      public static String sign_type = "RSA2";
    
      // 字符编码格式
      public static String charset = "utf-8";
    
      // 支付宝网关
      public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";
    
      public static String productCode ="QUICK_WAP_WAY";//H5
      public static String productCode_APP ="QUICK_MSECURITY_PAY";//App
    }

    6.工具使用:

    https://opendocs.alipay.com/open/291/106130

    展开全文
  • 现如今,手机支付已相当普遍,而作为开发人员应该对手机支付操作有所了解。而支付宝接口是支付宝提供的一个接口,用来对接软件应用程序在进行金钱交易使用。然后对于编程爱好者而言,想学习这一点就有点难,因为要想...

    1. 什么是支付宝接口(沙箱环境)?

    记录时间:2020年10月15日3:55

    现如今,手机支付已相当普遍,而作为开发人员应该对手机支付操作有所了解。而支付宝接口是支付宝提供的一个接口,用来对接软件应用程序在进行金钱交易使用。然后对于编程爱好者而言,想学习这一点就有点难,因为要想使用支付宝接口,必须前提是使用软件应用程序,软件应用程序需要向支付宝申请,提交一系列资料,这一点是实现不了的。这就对开发者增加了一定的难度,因为产品没有上线,然后需要对接支付宝接口就是很大的问题,所以出现了沙箱环境,具有虚拟的用户和管理员账户,进行实验测试是否对接成功。接下来就根据我的经验,简单的介绍一下我的使用和学习过程。

    使用技术+编程软件:

    1. springboot(idea)
    2. vue + elementui(HBuilderX)+ vue-qr(vue生成二维码框架)
    3. NATAPP(连接外网,实现支付宝回调)
    4. websocket(实现前端响应)

    步骤:

    1. 准备沙箱环境
    2. JAVA + springboot 中使用 SDK 连接支付宝接口配置
    3. 前端使用vue+elementui页面设计
    4. 需要注意点
    5. 结果测试
    1. 首先创建应用,这里是沙箱环境,先准备沙箱环境:
    • 百度搜索**支付宝蚂蚁金服**,登录支付包账号,出现如下显示:
      在这里插入图片描述

    • 这里是创建应用的地方,也就是说有项目要上线时,在这里申请。使用沙箱环境的话,点击左上角开放平台,然后往下拉,会出现沙箱二字,点击进入即可:

    在这里插入图片描述

    • 然后就可以看到支付宝官网介绍的沙箱环境的使用,其实官网已经介绍的非常详细了,如有小伙伴们看着嫌麻烦,可以根据我学习的步骤作为参考。
    • 在如何使用沙箱环境下点击沙箱应用链接,去配置自己的沙箱环境。
      在这里插入图片描述
    • 点击 i 符号,上面有提示链接,如何生成RSA2密钥,这里就不详细介绍了,官网写的非常明白,我这么笨的人也可以学会,相信小伙伴们也可以学会的。按照步骤会生成两个文件:应用公钥和应用私钥。记住,是应用公钥,而不是支付宝公钥。这里学习过程中没有使用证书模式
      在这里插入图片描述
      然后点击RSA2的设置/查看。将产生的应用公钥复制进去就可以了,而下面会生成支付宝公钥,在后续连接过程中非常重要,需要区分使用的是支付宝公钥还是应用公钥
      在这里插入图片描述
    1. JAVA + springboot 中使用 SDK 连接支付宝接口配置
      在这里插入图片描述
    • 这里是官网使用SDK的方法,这里使用旧版的方式,新版的方式我使用过程中出现某些问题不会解决。
      使用之前,先封装几个配置,第一个是连接支付宝的配置:
    import com.alipay.api.AlipayApiException;
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.internal.util.AlipaySignature;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 支付宝接口配置类
     */
    @Configuration
    public class PayConfig {
        // 请填写您的AppId,例如:2019091767145019(必填)
        private static final String appID = "2016102500758313";
        //应用私钥,这里修改生成的私钥即可(必填)
        private static final String privateKey = "";
        //支付宝公钥,而非应用公钥(必填)
        public static final String publicKey = "";
    	//默认即可(必填)
        public static final String charset = "utf-8";
    	//默认即可(必填)
        public static final String signType = "RSA2";
        @Bean
        public AlipayClient alipayClient(){
        	//沙箱环境使用https://openapi.alipaydev.com/gateway.do,线上环境使用https://openapi.alipay.com/gateway.do
            return new DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do", appID, privateKey, "json", charset, publicKey, signType);
        }
    	/**
    	 * 验签,是否正确
    	 */
        public static boolean checkSign(HttpServletRequest request){
            Map<String, String[]> requestMap = request.getParameterMap();
            Map<String, String> paramsMap = new HashMap<>();
            requestMap.forEach((key, values) -> {
                String strs = "";
                for(String value : values) {
                    strs = strs + value;
                }
                System.out.println(key +"===>"+strs);
                paramsMap.put(key, strs);
            });
            System.out.println();
            //调用SDK验证签名
            try {
                return  AlipaySignature.rsaCheckV1(paramsMap, PayConfig.publicKey, PayConfig.charset, PayConfig.signType);
            } catch (AlipayApiException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("*********************验签失败********************");
                return false;
            }
    
        }
    }
    
    

    然后封装一个支付宝回调的参数对象,这里就不需要自己手动去获取参数了

    import java.io.Serializable;
    
    /**
     * 支付宝回调参数
     */
    public class AliReturnPayBean implements Serializable {
        /**
         *
         */
        private static final long serialVersionUID = 1L;
    
        /**
         * 开发者的app_id
         */
        private String app_id;
    
        /**
         * 商户订单号
         */
        private String out_trade_no;
    
        /**
         * 签名
         */
        private String sign;
    
        /**
         * 交易状态
         */
        private String trade_status;
    
        /**
         * 支付宝交易号
         */
        private String trade_no;
    
        /**
         * 交易的金额
         */
        private String total_amount;
    
        public String getTotal_amount() {
            return total_amount;
        }
    
        public void setTotal_amount(String total_amount) {
            this.total_amount = total_amount;
        }
    
        public String getApp_id() {
            return app_id;
        }
    
        public void setApp_id(String app_id) {
            this.app_id = app_id;
        }
    
        public String getOut_trade_no() {
            return out_trade_no;
        }
    
        public void setOut_trade_no(String out_trade_no) {
            this.out_trade_no = out_trade_no;
        }
    
        public String getSign() {
            return sign;
        }
    
        public void setSign(String sign) {
            this.sign = sign;
        }
    
        public String getTrade_status() {
            return trade_status;
        }
    
        public void setTrade_status(String trade_status) {
            this.trade_status = trade_status;
        }
    
        public String getTrade_no() {
            return trade_no;
        }
    
        public void setTrade_no(String trade_no) {
            this.trade_no = trade_no;
        }
    
        @Override
        public String toString() {
            return "AliReturnPayBean [app_id=" + app_id + ", out_trade_no=" + out_trade_no + ", sign=" + sign
                    + ", trade_status=" + trade_status + ", trade_no=" + trade_no + "]";
        }
    }
    
    

    然后写一个控制层去连接支付宝,控制层必须是@Controller修饰,而不是@RestController修饰,因为支付宝的回调函数里面返回的是请求。具体事例如下:
    前提:在pom.xml 中导入SDK依赖:

    <dependency>
        <groupId>com.alipay.sdk</groupId>
        <artifactId>alipay-sdk-java</artifactId>
        <version>4.10.145.ALL</version>
    </dependency>
    
    package com.example.zhifubaozhifu.controller;
    
    
    import com.alibaba.fastjson.JSON;
    import com.alipay.api.AlipayApiException;
    import com.alipay.api.AlipayClient;
    import com.alipay.api.request.AlipayTradePrecreateRequest;
    import com.alipay.api.response.AlipayTradePrecreateResponse;
    import com.example.zhifubaozhifu.config.PayConfig;
    import com.example.zhifubaozhifu.util.AliReturnPayBean;
    import com.example.zhifubaozhifu.util.Shop;
    import com.example.zhifubaozhifu.util.WebSocket;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.math.BigDecimal;
    
    @Controller
    @Slf4j
    public class Test {
        @Autowired
        private AlipayClient alipayClient;
        @Autowired
        private WebSocket webSocket;
    
    
        @RequestMapping("/createQR")
        @ResponseBody
        public String send() throws AlipayApiException {
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); //创建API对应的request类
            // 在下面会介绍notifyUrl怎么来的
            request.setNotifyUrl("http://cv95x3.natappfree.cc/call");
            //同步回调地址
    //        request.setReturnUrl("");
            request.setBizContent("  {" +
    				"    \"primary_industry_name\":\"IT科技/IT软件与服务\"," +
    				"    \"primary_industry_code\":\"10001/20102\"," +
    				"    \"secondary_industry_code\":\"10001/20102\"," +
    				"    \"secondary_industry_name\":\"IT科技/IT软件与服务\"" +
    				" }");;
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            String path = "zhifu.jpg";
            if (response.isSuccess()) {
                System.out.println("调用成功");
                return response.getQrCode();
            } else {
                System.out.println("调用失败");
            }
            return "";
        }
    
    
        /**
         * 支付宝回调函数
         * @param request
         * @param response
         * @param returnPay
         * @throws IOException
         */
        @RequestMapping("/call")
        public void call(HttpServletRequest request, HttpServletResponse response, AliReturnPayBean returnPay) throws IOException {
            response.setContentType("type=text/html;charset=UTF-8");
            log.info("支付宝的的回调函数被调用");
            if (!PayConfig.checkSign(request)) {
                log.info("验签失败");
                response.getWriter().write("failture");
                return;
            }
            if (returnPay == null) {
                log.info("支付宝的returnPay返回为空");
                response.getWriter().write("success");
                return;
            }
            log.info("支付宝的returnPay" + returnPay.toString());
            //表示支付成功状态下的操作
            if (returnPay.getTrade_status().equals("TRADE_SUCCESS")) {
                log.info("支付宝的支付状态为TRADE_SUCCESS");
                //业务逻辑处理 ,webSocket在下面会有介绍配置
                webSocket.sendMessage("true");
            }
            response.getWriter().write("success");
        }
    }
    
    1. 前端使用vue+elementui页面设计:
      vue项目的搭建这里就不介绍,首先准备环境,添加 vue-qr 插件:
    npm install vue-qr --save
    

    前端代码:

    <template>
    	<div>
    		<!-- 支付按钮,模拟支付操作 -->
    		<van-button type="primary" @click="pay">支付</van-button>
    
    		<el-dialog :title="paySucc?'支付成功':'扫码支付'" :visible.sync="dialogVisible" width="16%" center>
    			<!-- 生成二维码图片 -->
    			<vueQr :text="text" :size="200" v-if="!paySucc"></vueQr>
    			<!-- 使用websocket监控是否扫描,扫描成功显示成功并退出界面 -->
    			<span class="iconfont icon-success" style="position: relative;font-size: 100px;color:#42B983;margin-left: 50px;top:-10px;" v-else></span>
    		</el-dialog>
    
    	</div>
    </template>
    
    <script>
    	import vueQr from 'vue-qr'
    	export default {
    		data() {
    			return {
    				dialogVisible: false,
    				text: "",
    				paySucc: false
    			}
    		},
    		components: {
    			vueQr
    		},
    		methods: {
    			pay() {
    				let _this = this;
    				_this.paySucc = false;
    				_this.dialogVisible = true;
    				this.axios.request("http://localhost:8081/createQR")
    					.then((response) => {
    						_this.text = response.data;
    						_this.dialogVisible = true;
    						//使用webSocket发送请求,下面会简单介绍websocket使用
    						if ("WebSocket" in window) {
    							// 打开一个 web socket
    							var ws = new WebSocket("ws://localhost:8081/bindingRecord");
    
    							ws.onopen = function() {
    								// Web Socket 已连接上,使用 send() 方法发送数据
    								// ws.send("data");
    								// alert("数据发送中...");
    							};
    
    							ws.onmessage = function(evt) {
    								var received_msg = evt.data;
    								// alert("数据已接收..." + evt.data);
    								if (Boolean(evt.data)) {
    									_this.paySucc = true;
    									setTimeout(() => {
    										_this.dialogVisible = false;
    									}, 3 * 1000);
    								}
    								ws.close();
    
    							};
    							
    							ws.onclose = function() {
    								// // 关闭 websocket
    								console.log("连接已关闭...");
    							};
    						} else {
    							// 浏览器不支持 WebSocket
    							alert("您的浏览器不支持 WebSocket!");
    						}
    					}).catch((err) => {
    						console.log(err)
    					})
    			},
    			back(dataUrl, id) {
    				console.log(dataUrl, id)
    			}
    		}
    	}
    </script>
    
    <style>
    	.btn {
    		margin-left: 100px;
    	}
    </style>
    
    
    1. 这样前后端代码就准备就绪了,再上面的代码中有两个需要注意的
    • 第一个问题是:notifyUrl使用的url是外网地址,并不是IP地址,否则会无法回调。但是在学习环境下使用不了外网地址。这就需要使用**NATAPP**。百度搜索NATAPp官网,点进去下载,它是一个natapp.exe 应用,这有这个。在官网注册账号,点击购买免费隧道(免费隧道只能购买两个,要珍惜哦。隧道协议写web,其他的就按要本地环境配置就可以了)。购买之后就会有下面一条自己的隧道
      在这里插入图片描述
      双击natapp.exe ,进入控制台,输入以下命令,开启隧道:
    # 这里的值是上面的authtoken的值
    natapp --authtoken=

    之后如下显示:
    在这里插入图片描述
    这里的外网连接地址,就是notifyUrl的地址,然后再加上方法mapping路径即可,如我的是:http://cv95x3.natappfree.cc/call

    • 第二个问题是:支付成功后,回调函数执行了,如何告诉前端我已经支付成功,同时关闭扫描二维码按钮,这里就用到了websocket,这里不详细介绍websocket是什么,只要知道一点,它是可以监听到后端是否发送信息。首先在pom.xml中导入依赖:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>
    

    然后创建一个webconfig的配置类:

    package com.example.zhifubaozhifu.util;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    import javax.websocket.OnClose;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    /**
     * @desc: WebSocket服务
     *
     **/
    //连接webSocket服务的URL
    @ServerEndpoint("/bindingRecord")
    @Component
    @Slf4j
    public class WebSocket {
    
        private Session session;
        private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
    
        /**
         * 新建webSocket配置类
         * @return
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
        /**
         * 建立连接
         * @param session
         */
        @OnOpen
        public void onOpen(Session session) {
            this.session = session;
            webSockets.add(this);
            log.info("【新建连接】,连接总数:{}", webSockets.size());
        }
    
        /**
         * 断开连接
         */
        @OnClose
        public void onClose(){
            webSockets.remove(this);
            log.info("【断开连接】,连接总数:{}", webSockets.size());
        }
    
        /**
         * 接收到信息
         * @param message
         */
        @OnMessage
        public void onMessage(String message){
            log.info("【收到】,客户端的信息:{},连接总数:{}", message, webSockets.size());
        }
    
        /**
         * 发送消息
         * @param message
         */
        public void sendMessage(String message){
            log.info("【广播发送】,信息:{},总连接数:{}", message, webSockets.size());
            for (WebSocket webSocket : webSockets) {
                try {
                    webSocket.session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    log.info("【广播发送】,信息异常:{}", e.fillInStackTrace());
                }
            }
        }
    
    }
    

    然后使用的时候调用方法onMessage即可接收消息,使用onMessage即可广发消息。

    前端使用步骤:

    <script type="text/javascript">
       function WebSocketTest()
       {
          if ("WebSocket" in window)
          {
             alert("您的浏览器支持 WebSocket!");
             
             // 打开一个 web socket
             var ws = new WebSocket("ws://localhost:9998/echo");
              
             ws.onopen = function()
             {
                // Web Socket 已连接上,使用 send() 方法发送数据
                ws.send("发送数据");
                alert("数据发送中...");
             };
              
             ws.onmessage = function (evt) 
             { 
                var received_msg = evt.data;
                alert("数据已接收...");
             };
              
             ws.onclose = function()
             { 
                // 关闭 websocket
                alert("连接已关闭..."); 
             };
          }
          
          else
          {
             // 浏览器不支持 WebSocket
             alert("您的浏览器不支持 WebSocket!");
          }
       }
    </script>
    

    想详细了解的话,可以去菜鸟教程学习。

    使用思路: 前端先创建websocket , 连接到后端websocket ,这样才能将websocket通道连接。当支付成功之后,后端向前端反馈支付成功信息,前端监控接收到消息后做处理,即关闭二维码对话框。

    1. 测试结果:
      在这里插入图片描述
      然后下载支付宝沙箱版手机即可扫描模拟支付,在蚂蚁金服的沙箱环境中就有二维码下载,如下图:
      加粗样式
      这里指记录了支付到回调处理的操作,再这之上还可进行进一步的封装。

    搞定,记录结束。

    结束时间:2020年10月15日6:12

    展开全文
  • Java对接支付宝的支付、退款、提现

    千次阅读 2021-01-28 14:41:21
    本篇主要是正对Java对接支付宝的常用功能,需要开通个人的沙箱环境和内网穿透(我用了阿里云服务器)。 集成前提:开发者在集成和开发前需要了解一下常用的接入方式和架构建议,如下图所示: 1、登录网页版的个人...
  • 关于支付宝即时收款接口的对接过程,很简单,也有很多人发过,我这里就不在啰嗦了,对接完成后,在线支付成功后的回调,相对来说,是个难点,,我重点分享下我的经验。 我在开发二代旅游CMS(http://www.erdaicms.com...
  • 这个接口主要是实现企业支付宝APP支付已经签约完成的,想对接到手机网站实现手机网站支付来用的。 如果对接到PC网站,用户支付的时候就是扫码支付,网站出付款码,用户扫码完成支付。 如果对接到APP平台,正常跟...
  • 个人网站对接支付宝支付详细教程 本人也是第一次做这个,目的是在于学习,因为我没有企业账号,所以用的是自己的支付宝,所以第一次要先在平台上注册。 支付宝对接:网页&移动开发流程文档 第一步:支付宝开放平台 ...
  • 史上最简单Java服务端对接支付宝支付教程,前端为APP。 一、支付业务流程 官方开发文档:https://docs.open.alipay.com/204/105297/ 下单时前端请求后台获取支付字符串 后台接收到请求支付字符串的请求,先处理...
  • java对接支付宝支付demo,支付宝官方案例。代码很全,拿来就可以用
  • 当然就算会员可以在网站上建立自己的现金账户,提供支付宝支付功能也不失为另一种方便快捷的支付方式,这可以给客户提供更多可选的支付方式。 首先,网上购物系统必须与支付宝公司签订合作协议,以确保从本购物网站...
  • 网络大都加密,这里解密,去了授权
  • java对接支付宝支付-最新全过程

    千次阅读 2020-10-29 14:46:44
    /** * 支付接口 */ @PostMapping("/pay") @ApiOperation(value = "调起进行支付", notes = "调起进行支付") @SneakyThrows public ResponseEntity<?> pay(HttpServletResponse httpResponse, @Valid @RequestBody ...
  • 商户对接支付宝支付

    2019-10-23 10:15:52
    支付宝开发常用连接 https://e.alipay.com/shop.htm#/shop?_k=ksd9xt 门店中心 支付宝在线...将签名工具生成的公钥上传到下图的位置 程序中使用的公钥是支付平台返回的支付宝公钥,私钥是工具生成的 还需要商户的应用ID
  • 之前在项目中使用过支付宝的沙箱测试支付和实际开发支付,是关于App对接支付宝接口的,由于前段时间有朋友询问怎么对接网页支付,通过研究支付包的开发文档,在这里总结一下对接支付宝的App支付接口和网页支付接口的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,336
精华内容 11,334
关键字:

对接支付