小程序支付类型接入京东支付

一、情景描述

当前项目想在微信小程序付款时添加上京东支付支付类型,效果如下
https://img-blog.csdnimg.cn/direct/c5fd36bcc199465cbb5ecfbb3b440b1c.png
普通的付款方式可以直接付款就能完成支付,但京东支付无法在小程序上直接付款,他需要复制生成的链接,然后打开京东app然后在京东平台上付款。
在这里插入图片描述
所以,我们首先需要了解京东支付的支付流程

二、京东支付实现流程

京东支付跟普通支付不同之处就是无法在当前平台完成支付,需要复制口令前往京东app,在京东app里进行支付操作
具体可查看开放文档:
https://mer.jd.com/open/
文档中也提供了大部分接口demo,可以下载参考
简单概括步骤分为3步:

1、下单接口

调用这个接口,成功的话在响应体中有一个我们需要的数据pay_url,支付链接,我尝试了一下,点击可以进入到京东付款页面,但是我们不要直接使用,要把这个字段封装成金口令。
(注意:设置的请求体中有一个字段callbackUrl回调路径,设置这个值在支付完成后京东会调用这个路径的接口,见3、编写回调方法验证支付订单)
在这里插入图片描述
下单方法代码参考如下

//京东下单支付生成金口令public static ReturnValueDomain<String> pay(Tcorderinfo tcorderinfo ) throws Exception {ReturnValueDomain<String> ret = new ReturnValueDomain<String>();logger.debug("========进入京东支付方法,进入pay=========");if (NonUtil.isNon(tcorderinfo)) {return ret.setFail("京东支付订单不可为空!");}// 得到openidString openid = tcorderinfo.getOpenid();int fee = 0;// 得到小程序传过来的价格,注意这里的价格必须为整数,1代表1分,所以传过来的值必须*100;if (NonUtil.isNon(tcorderinfo.getAdvancepay())) {fee = Integer.parseInt(tcorderinfo.getOrderfee());} else {fee = Integer.parseInt(tcorderinfo.getAdvancepay());}double total_amount = MathHelper.div(fee, 100, 2);logger.debug("==========支付费用/元=={}=====", total_amount);// 订单编号String did = tcorderinfo.getOrderid();// 订单标题-商品名称String title = tcorderinfo.getTradename();Map<String, Object> requestParam = new HashMap<>();//代理商号
//        requestParam.put("agentNum", agentNum);//商户号requestParam.put("customerNum", customerNum);//店铺号
//        requestParam.put("shopNum", shopNum);//机具号
//        requestParam.put("machineNum", machineNum);
//        requestParam.put("requestNum", generateId());//订单号requestParam.put("requestNum", tcorderinfo.getOrderid());//订单号requestParam.put("authCode", tcorderinfo.getOpenid());//openidrequestParam.put("bankType", bankType);//支付类型requestParam.put("orderAmount", total_amount+"");//支付金额requestParam.put("callbackUrl", callbackUrl);requestParam.put("source", source);requestParam.put("orderType", orderType);requestParam.put("payModel", payModel);requestParam.put("payType", payType);requestParam.put("subOrderType", subOrderType);requestParam.put("businessType", businessType);requestParam.put("paySource", paySource);requestParam.put("version", "V4.0");requestParam.put("completeUrl", completeUrl);//支付自定义页面Map<String, String> extraMap = new HashMap<>();extraMap.put("userAgent", "UnionPay / 1.0 CEBBANK");requestParam.put("extraInfo", JSON.toJSON(extraMap));String response = OpenapiRequestUtil.postOpenapi(api_order,accessKey,secretKey, requestParam);JSONObject res = JSONObject.parseObject(response);//添加判断if (!(Boolean) res.get("success")){logger.error("京东下单接口失败:{}",response);return ret.setFail((String) res.get("msg"));}//解析String qrCode = JSONObject.parseObject(res.get("bankRequest").toString()).get("PAY_URL").toString();requestParam = new HashMap<>();JSONObject reqData = new JSONObject();JSONObject request = new JSONObject();request.put("url",qrCode+"&sourceID=xxx");request.put("keyChannel",keyChannel);request.put("sourceCode",sourceCode);request.put("deviceInfo","");reqData.put("request",request);Map<String,Object> map = new HashMap<>();String url = prize_url;//金口令地址map.put("reqData",reqData);System.out.println("金口令请求体"+map);String str = HttpUtil.postFormData(url, map);System.out.println("金口令返回1"+str);res = JSONObject.parseObject(str);//添加判断String code = JSONObject.parseObject(res.get("resultData").toString()).get("code").toString();if (code!=null && "000".equals(code)){} else {String msg = JSONObject.parseObject(res.get("resultData").toString()).get("msg").toString();logger.debug("调用金口令接口出现异常:{}",msg);ret.setFail("京东支付生成金口令出现异常");}//解析String data = JSONObject.parseObject(JSONObject.parseObject(res.get("resultData").toString()).get("data").toString()).get("code").toString();logger.debug("获取金口令:{}",data);return ret.setSuccess("生成金口令响应",str);}

httpUtil工具类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Set;public class HttpUtil {private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);public static String postFormData(String url, Map<String, Object> map) throws Exception {BufferedReader in = null;URL urls = new URL(url);HttpURLConnection connection = null;OutputStream outputStream = null;String rs = "";try {connection = (HttpURLConnection) urls.openConnection();connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=----footfoodapplicationrequestnetwork");connection.setDoOutput(true);connection.setDoInput(true);connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");connection.setRequestProperty("Accept", "*/*");connection.setRequestProperty("Range", "bytes=" + "");connection.setConnectTimeout(8000);connection.setReadTimeout(20000);connection.setRequestMethod("POST");StringBuffer buffer = new StringBuffer();outputStream = connection.getOutputStream();Set<Map.Entry<String, Object>> entries = map.entrySet();for (Map.Entry<String, Object> entry : entries) {// 每次都清空buffer,避免写入上次的数据buffer.delete(0, buffer.length());buffer.append("------footfoodapplicationrequestnetwork\r\n");Object value = entry.getValue();if (!(value instanceof File)) {buffer.append("Content-Disposition: form-data; name=\"");buffer.append(entry.getKey());buffer.append("\"\r\n\r\n");buffer.append(entry.getValue());buffer.append("\r\n");outputStream.write(buffer.toString().getBytes());} else {buffer.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"; filename=\"" + ((File) entry.getValue()).getName() + "\"\r\n");buffer.append("Content-Type: " + "zip" + "\r\n\r\n");outputStream.write(buffer.toString().getBytes());File file = (File) entry.getValue();DataInputStream ins = new DataInputStream(new FileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[1024];while ((bytes = ins.read(bufferOut)) != -1) {outputStream.write(bufferOut, 0, bytes);}// 文件流后面添加换行,否则文件后面的一个参数会丢失outputStream.write("\r\n".getBytes());}}if (entries != null && map.size() > 0) {buffer.delete(0, buffer.length());buffer.append("------footfoodapplicationrequestnetwork--\r\n");}outputStream.write(buffer.toString().getBytes());try {connection.connect();if (connection.getResponseCode() == 200) {in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));String line = "";while ((line = in.readLine()) != null) {rs += line;}}} catch (Exception e) {logger.error("发生异常",e);rs = null;}return rs;} finally {try {outputStream.close();if (in != null){in.close();}} catch (Exception e) {logger.error("发生异常",e);}outputStream = null;if (connection != null)connection.disconnect();connection = null;}}
}

2、生成金口令

将下单接口返回的pay_url,拼接上sourceID(京东工作人员会提供)作为url字段参数,去调用金口令接口
在这里插入图片描述
调用成功后,可以将生成的金口令响应给前端

3、编写回调方法验证支付订单

在京东平台付款成功后,京东平台会调用这个接口,我们需要做的2步:
(1)验证签名
通过签名验证订单身份,保证订单是自己的订单
(验证签名的demo京东线上文档中也提供了,可以下载参考)
(2)验证通过后编写付款后的业务逻辑

当然,还有退款接口,下载账单接口等,文档中都提供了,可以根据项目情况类比去开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机云控制发电机组 有网络随时随地操控监控运行

GenCloudTM 发电机组云控系统简介 Ver2.0 目录 公司简介…… …………………………… ………………………………………………1概 述…… …………………………… ………………………………………………1主要功能及特点………… …………… ………… ………………………………

Mac基于VMware安装CentOS

流程偏长&#xff0c;下一步根本点不完&#xff1b; 01 首先&#xff0c;明确下两款软件的版本信息&#xff1b; VMware是【VMware-Fusion-13.5.0】CentOS是【CentOS-7-x86_64-Minimal-1908】&#xff1b; VMware用来管理虚拟机系统&#xff0c;安装就不多说了&#xff0c;双…

【c语言】深入理解指针(2)

1. 字符指针变量 可以利用字符指针存放字符数组来间接存放字符串。 int main() {char arr[10] "abcdef";char* p arr;printf("p %s\n", p);return 0; } 那我们可不可以直接给字符指针存放字符串呢&#xff1f; int main() {char* p1 "abcde…

51单片机学习笔记 --步进电机驱动说明

文章目录 工作原理代码编写驱动方式全步进驱动半步进驱动微步进驱动 工作原理 工作原理简要说明&#xff0c;和单片机一起配合使用的步进电机多为28BYJ28 五线四相步进电机&#xff0c;配合ULN2003驱动板进行控制&#xff0c;如图所示&#xff0c;对于扭矩、精度要求较高的还有…

基于Springboot的高校心理教育辅导设计与实现(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的高校心理教育辅导设计与实现(有报告)。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…

20240202在WIN10下使用fast whisper缺少cudnn_ops_infer64_8.dll

20240202在WIN10下使用fast whisper缺少cudnn_ops_infer64_8.dll 2024/2/2 10:48 https://blog.csdn.net/feinifi/article/details/132548556 Could not locate cudnn_ops_infer64_8.dll. Please make sure it is in your library path!解决办法 安装cuDNN c:\faster-whisper-…

小程序中picker多列选择器

需求&#xff1a;实现类似省市联动的效果&#xff0c;选择第一列后&#xff0c;第二列数据变化 html部分: <view class"section"><view>多列选择器</view><picker mode"multiSelector" bindchange"bindMultiPickerChange"…

Unity_ShaderGraph示例项目启动

Unity_ShaderGraph示例项目启动 大前提不变:URP模板,Unity2023.1.19使用 Shader Graph - Unity 手册Shader Graph 是一个工具,能够让您直观地构建着色器。您可以在图形框架中创建并连接节点,而不必手写代码。Shader Graph 提供了能反映所作更改的即时反馈,对于不熟悉着色…

flutter抓包绕过

lutter的证书校验 起因&#xff1a; 最近工作上让做个app的复测&#xff0c;把apk发我后&#xff0c;开始尝试挂代理抓包&#xff0c;结果发现抓不到 为是证书没弄好&#xff0c;想着前几天不是刚导入了吗&#xff08;雾&#xff09;。又重新导入了下还是不行。然后各种lsp模…

【TCP】四次挥手(终止连接)

前言 TCP&#xff08;传输控制协议&#xff09;是互联网协议&#xff08;IP&#xff09;中的一种重要传输层协议&#xff0c;用于在通信的计算机之间建立可靠的、有序的和错误校验的数据传输。在TCP连接中&#xff0c;数据传输是双向的&#xff0c;因此需要一种机制来开始和结…

【数据结构】单向链表实现 超详细

目录 一. 单链表的实现 1.准备工作及其注意事项 1.1 先创建三个文件 1.2 注意事项&#xff1a;帮助高效记忆和理解 2.链表的基本功能接口 2.0 创建一个 链表 2.1 链表的打印 3.链表的创建新节点接口 4.链表的节点插入功能接口 4.1 尾插接口 4.2 头插接口 4.3 指定位…

【无标题】yarn报错 “https://registry.npm.taobao.org/...: certificate has expired“如何处理

前言 今天在jenkins打包项目时yarn打包报错&#xff0c;查看log发现npm淘宝镜像报错 原因 在 1 月 22 日&#xff0c;淘宝原镜像域名&#xff08;registry.npm.taobao.org&#xff09;的 HTTPS 证书正式到期。如果想要继续使用&#xff0c;需要将 npm 源切换到新的源&#…

Dockerfile构建Nginx访问说明

Dockerfile使用情况 20210903 Dockerfile ,Nginx 参考地址&#xff1a;https://yeasy.gitbook.io/docker_practice/image/build 编写简单Dockerfile 在一个空白目录中&#xff0c;建立一个文本文件&#xff0c;并命名为 Dockerfile&#xff1a; $ mkdir mynginx $ cd myngin…

跟着cherno手搓游戏引擎【18】抽象Shader、项目小修改

抽象&#xff1a; Shader.h: #pragma once #include <string>namespace YOTO {class Shader {public:virtual~Shader()default;virtual void Bind()const0;virtual void UnBind()const0;static Shader* Create(const std::string& vertexSrc, const std::string&am…

window 安装 jenkins 编写脚本

set JAVA_HOMED:\RuanJianKaiFa\jdk\jdk11 set CLASSPATH.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOMe%\lib\tools.jar; set Path%JAVA_HOME%\bin; java -jar jenkins.war 下载jenkins.war包&#xff0c;编写一个txt文档&#xff0c;把脚本复制进去&#xff0c;修改文件后缀为.bat文件…

MySQL EXPLAIN查询执行计划

EXPLAIN 可用来查看SQL执行计划&#xff0c;常用来分析调试SQL语句&#xff0c;来使SQL语句达到更好的性能。 1 前置知识 在学习EXPLAIN 之前&#xff0c;有些基础知识需要清楚。 1.1 JSON类型 MySQL 5.7及以上版本支持JSON数据类型。可以将数组存为JSON格式的字符串&#…

本体匹配方法概述

目录 前言1 基于术语匹配的方法1.1 字符串匹配1.2 语言方法 2 基于虚拟文档的方法3 基于结构的匹配方法3.1 结构信息利用3.2 Anchor-prompt方法 4 大型本体匹配4.1 本体划分4.2 匹配分块4.3 实体间映射 结语 前言 本文将深入探讨本体匹配的不同方法&#xff0c;从基于术语匹配…

DES加密原理

DES加密算法综合运用了置换、代替、代数等多种密码技术&#xff0c;具有设计精 巧、实现容易、使用方便等特点。DES加密算法的明文、密文和密钥的分组长度 都是64位&#xff0c;详细的DES加密算法结构如图6-10所示。 图6-10 DES加密算法结构图 DES加密过程如下所示&#xff…

2024PMP考试新考纲-【业务环境领域】典型真题和很详细解析(3)

华研荟继续分享【业务环境Business Environment领域】在新考纲下的真题&#xff0c;帮助大家体会和理解新考纲下PMP的考试特点和如何应用所学的知识和常识&#xff08;经验&#xff09;来解题&#xff0c;并且举一反三&#xff0c;一次性3A通过2024年PMP考试。 2024年PMP考试新…

0202-1-处理机调度与死锁

第三章:处理机调度与死锁 处理机调度算法的目标 处理机调度算法的共同目标 资源利用率:CPU的利用率CPU有效工作时间/(CPU有效工作时间CPU空闲等待时间)公平性平衡性策略强制执行 批处理系统的目标 平均周转时间短系统吞吐量高处理机利用率高 分时系统的目标 响应时间快均…