java实现对接建行支付及其回调

最近公司要对接建行支付,也是查了很多资料,走了很多弯路,还问了建行的技术员,现把它记录下来,直接上代码。

调用支付所需常量

@Value("${ccb.MERCHANTID}")
    private String MERCHANTID;  //商户代码,固定写死的,需要申请
    //@Value("${ccb.POSID}")  //这里用yml提取出来就会报错..
    private String POSID = "xxxxx";           //商户柜台代码,固定写死的,需要申请
    @Value("${ccb.BRANCHID}")
    private String BRANCHID;  //分行代码,固定写死的,需要申请
    @Value("${ccb.PUB32TR2}")
    private String PUB32TR2; //公钥后30位
    private String BEGORDERID = "";
    private String ENDORDERID = "";
    private String QUPWD = "xxxxx";//这里写建行支付的商户密码
    //交易码 这个参数的值是固定的,不可以修改
    private String TXCODE = "xxxxx";
    /*必输项
    1页面形式
    2文件返回形式 (提供TXT和XML格式文件的下载)
    3 XML页面形式*/
    private String SEL_TYPE = "3";
    /*不知道干嘛用的*/
    private String CHANNEL = "";
    /*不知道干嘛用的*/
    private String OPERATOR = "";

    @Autowired
    private JinshiCCBPayMapper jinshiCCBPayMapper;

    @Override
    public JSONObject CCBPay(JSONObject jsonObject) {
        String CURCODE = "01";     //付款币种,固定写01 代表支付金额
        String TXCODE = "530550";  //由建行统一分配为530550
        String REMARK1 = "";
        String REMARK2 = "";
        String RETURNTYPE = "3"; // 返回类型,固定参数是3  ,代表是返回带url的支付信息
        String TIMEOUT = "";
        String ORDERID = String.valueOf(jsonObject.get("orderId"));    //订单号  由商户提供,最长40位,不能重复
        String PAYMENT = String.valueOf(jsonObject.get("payment"));//支付金额
        StringBuffer tmp = new StringBuffer();
        tmp.append("MERCHANTID=");
        tmp.append(MERCHANTID);
        tmp.append("&POSID=");
        tmp.append(POSID);
        tmp.append("&BRANCHID=");
        tmp.append(BRANCHID);
        tmp.append("&ORDERID=");
        tmp.append(ORDERID);
        tmp.append("&PAYMENT=");
        tmp.append(PAYMENT);
        tmp.append("&CURCODE=");
        tmp.append(CURCODE);
        tmp.append("&TXCODE=");
        tmp.append(TXCODE);
        tmp.append("&REMARK1=");
        tmp.append(REMARK1);
        tmp.append("&REMARK2=");
        tmp.append(REMARK2);
        tmp.append("&RETURNTYPE=");
        tmp.append(RETURNTYPE);
        tmp.append("&TIMEOUT=");
        tmp.append(TIMEOUT);
        tmp.append("&PUB=");
        tmp.append(PUB32TR2);
        Map map = new HashMap();
        map.put("CCB_IBSVersion", "V6");
        map.put("MERCHANTID", MERCHANTID);
        map.put("BRANCHID", BRANCHID);
        map.put("POSID", POSID);
        map.put("ORDERID", ORDERID);
        map.put("PAYMENT", PAYMENT);
        map.put("CURCODE", CURCODE);
        map.put("TXCODE", TXCODE);
        map.put("REMARK1", REMARK1);
        map.put("REMARK2", REMARK2);
        map.put("RETURNTYPE", RETURNTYPE);
        map.put("TIMEOUT", TIMEOUT);
        map.put("MAC", MD5.md5Str(tmp.toString()));
        // 这个url是建设银行指定的,尽量不要换
        String ret = HttpClientUtil.httpPost("https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6", map);

        QrURLDemo qrURLDemo = JSON.parseObject(ret, QrURLDemo.class);
        // 这个url触发get请求会获取到一个新的页面
        String s = HttpClientUtil.httpGet(qrURLDemo.getPAYURL(), "UTF-8");

        //获取QRURL
        QrURLDemo qrURLDemo1 = JSON.parseObject(s, QrURLDemo.class);
        String decode = URLDecoder.decode(qrURLDemo1.getQRURL());
        String code = qrURLDemo1.getSUCCESS();
        // 安卓通过这个url就可以支付了
        JSONObject json = new JSONObject();
        json.put("decode",decode); //返回的这个decode就是支付所需跳转的url
        json.put("code",code); //这个是状态码
        //还会返回其他东西,我这里只需要这两个,所以只写了url和code
        return json;
    }
附 yml文件里配置的参数
ccb:
  # 商户代码,固定写死的,需要申请
  MERCHANTID: xxxxxxx
  POSID: xxxxxxx # 商户柜台代码,固定写死的,需要申请
  BRANCHID: xxxxxxx # 分行代码,固定写死的,需要申请
  CURCODE: xxxxxxx  #付款币种,固定写01 代表支付金额
  TXCODE: xxxxxxx  # 由建行统一分配为530550
  PUB32TR2: xxxxxxx # 公钥后30

微信支付界面
在这里插入图片描述
支付完成后,建行会自动调用回调地址,这个地址是在建行商户平台配置的,反馈有两种,网页反馈(方法:get)和服务器反馈(方法:post),请看下图
页面反馈:付款人付款完成后,点击“返回商户网站”按钮,触发页面反馈
服务器反馈:只要支付成功,无需触发,由建行支付网关,以post 方法,发信息给反馈URL
还分为网上银行和手机银行反馈,网上银行就是微信支付宝调用url支付,手机银行就是建行手机银行支付客户端,其实手机、网银,区分不是很严格,一般都设置成一样的,同一笔支付,可能会触发多渠道的同时反馈。所以,反馈机制,在响应的时候,是允许重复的。一般来说,服务器、页面,是写成两个不同的回调处理。或者,加个条件判断,同时允许post和get,也行。写成一个,就不太好判断反馈的来源了。写成两个,再通过日志,能区分反馈的来源。

在这里插入图片描述
支付完成后,出现这个页面,如果用户不点完成的话,直接左上角叉叉掉,服务器反馈有,页面反馈没有

付款这个环节不能携带任何参数显示出来
在这里插入图片描述
我这里页面反馈和服务器反馈写的不同方法,请求方式不同,服务器反馈主要是操作数据库,更新支付成功信息到数据库,页面反馈主要是用来展示成功的页面,订单信息等等展示给用户

/**
     * 支付回调(页面反馈 get)付款人付款完成后,点击“返回商户网站”按钮,触发页面反馈。
     *
     * @return
     */
    @GetMapping("/payCallBackForPage")
    @ResponseBody
    public SuccessVo payCallBackForPage(PayCallBackEntity payCallBackEntity,
                                        HttpServletResponse response) throws Exception {
        System.out.println("payCallBackEntity = " + payCallBackEntity);
        String success = payCallBackEntity.getSUCCESS();
        String orderId = payCallBackEntity.getORDERID();
        String payment = payCallBackEntity.getPAYMENT();
        System.out.println("success: -" + success);
        System.out.println("orderId: -" + orderId);
        if ("Y".equals(success)) {
            Map<String, Object> map = jinshiCCBPayService.selectByOrderId(orderId);
            Object returnCode = map.get("returnCode");
            Object returnMsg = map.get("returnMsg");
            logger.info("returnCode:  " + returnCode);
            logger.info("returnMsg:  " + returnMsg);
            if ("000000".equals(returnCode)) {
                //返回 "000000" 说明此订单号已支付成功
                //写支付成功以后的操作
                //todo
            }
        } else {
        	//支付失败
        }
        return new SuccessVo();
    }

其中用到了根据订单号查询订单的方法,如下:

@Override
    public Map<String, Object> selectByOrderId(String orderId) {
        //订单号  如果有了订单号,下面的 ORDERDATE BEGORDERTIME ENDORDERTIME 就无效了..所以就置空了.
        String ORDERID = orderId;
        String ORDERDATE = "20200114";  // 因为有ORDERID,所以这个字段无效了,但是不能删
        String BEGORDERTIME = "00:00:00";// 因为有ORDERID,所以这个字段无效了,但是不能删
        String ENDORDERTIME = "23:59:59";// 因为有ORDERID,所以这个字段无效了,但是不能删
        //txcode=410408
		/* 流程类型
		必输项
		0支付流水
		1退款流水*/
        String TYPE = "0";
		/*必输项(当日只有未结算流水可供查询)
		0 未结算流水
		1 已结算流水*/
        String KIND = "1";
		/*必输项
		0失败
		1成功
		2不确定
		3全部(已结算流水查询不支持全部)*/
        String STATUS = "1";
        //页码必输项,输入将要查询的页码。
        String PAGE = "1";
        String xmlString = this.getStringByHttpClient(ORDERDATE, BEGORDERTIME, ENDORDERTIME, ORDERID, TYPE, KIND, STATUS, PAGE);
        Document document = (Document) this.getDocumentByXMLStr(xmlString);
        List<QUERYORDER> queryorders = document.getQUERYORDER();
        Map<String, Object> resultMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(queryorders)) { // 如果没有查询到定单就是空的
            QUERYORDER queryOrder = queryorders.get(0); //因为只有一个结果,所以就获取索引为0的元素
            resultMap.put("queryOrder", queryOrder);
        }
        //不管查询成功查询失败都会有这个消息
        resultMap.put("returnCode", document.getRETURN_CODE());
        resultMap.put("returnMsg", document.getRETURN_MSG());
        return resultMap;
    }
    /**
     * 发送请求获取 String格式的字符串
     *
     * @param ORDERDATE
     * @param BEGORDERTIME
     * @param ENDORDERTIME
     * @param ORDERID
     * @param TYPE
     * @param KIND
     * @param STATUS
     * @param PAGE
     * @return string 格式的xml
     */
    private String getStringByHttpClient(Object ORDERDATE, Object BEGORDERTIME, Object ENDORDERTIME, String ORDERID, String TYPE, String KIND, String STATUS, String PAGE) {
        String param = "MERCHANTID=" + MERCHANTID + "&BRANCHID=" + BRANCHID + "&POSID=" + POSID + "&ORDERDATE=" + ORDERDATE + "&BEGORDERTIME=" + BEGORDERTIME
                + "&ENDORDERTIME=" + ENDORDERTIME + "&BEGORDERID=" + BEGORDERID + "&ENDORDERID=" + ENDORDERID + "&QUPWD=&TXCODE=" + TXCODE
                + "&SEL_TYPE=" + SEL_TYPE + "&OPERATOR=" + OPERATOR;
        if ("410408".equals(TXCODE)) {
            param = "MERCHANTID=" + MERCHANTID + "&BRANCHID=" + BRANCHID + "&POSID=" + POSID + "&ORDERDATE="
                    + ORDERDATE + "&BEGORDERTIME=" + BEGORDERTIME + "&ENDORDERTIME=" + ENDORDERTIME + "&ORDERID="
                    + ORDERID + "&QUPWD=&TXCODE=" + TXCODE + "&TYPE=" + TYPE + "&KIND=" + KIND + "&STATUS=" + STATUS +
                    "&SEL_TYPE=" + SEL_TYPE + "&PAGE=" + PAGE + "&OPERATOR=" + OPERATOR + "&CHANNEL=" + CHANNEL;
        }
        Map map = new HashMap();
        map.put("MERCHANTID", MERCHANTID);
        map.put("BRANCHID", BRANCHID);
        map.put("POSID", POSID);
        map.put("ORDERDATE", ORDERDATE);
        map.put("BEGORDERTIME", BEGORDERTIME);
        map.put("ENDORDERTIME", ENDORDERTIME);
        map.put("BEGORDERID", BEGORDERID);
        map.put("ENDORDERID", ENDORDERID);
        map.put("QUPWD", QUPWD);
        map.put("TXCODE", TXCODE);
        if ("410408".equals(TXCODE)) {
            map.put("TYPE", TYPE);
            map.put("KIND", KIND);
            map.put("STATUS", STATUS);
            map.put("ORDERID", ORDERID);
            map.put("PAGE", PAGE);
            map.put("CHANNEL", CHANNEL);
        }
        map.put("SEL_TYPE", SEL_TYPE);
        map.put("OPERATOR", OPERATOR);
        map.put("MAC", MD5.md5Str(param));
        // 调用银行的接口 基本是固定的地址
        String s = HttpClientUtil.httpPost("https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?", map);
        //删除字符串防止解析xml报错
        s = s.replaceAll("\\n", "").
                replaceAll("\\t", "").
                replaceAll("\\r", "");
        return s;
    }

    /**
     * 从 string 格式的xml 里面提出取出 Document 实体类
     * @param ret string 格式的xml
     * @return
     */
    private Object getDocumentByXMLStr(String ret) {
        XStream xStream = new XStream();
        xStream.alias("DOCUMENT", Document.class);
        xStream.processAnnotations(Document.class);
        XStream.setupDefaultSecurity(xStream);
        xStream.allowTypesByWildcard(
                new String[]{"com.xxxxx.**"}
        );
        return xStream.fromXML(ret);
    }

以下的实体类省略getset方法
Document 实体类

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

import java.util.List;
@XStreamAlias("DOCUMENT")
public class Document {
	@XStreamImplicit(itemFieldName ="QUERYORDER")
	private List<QUERYORDER> QUERYORDER ; // 查询订单

	private String RETURN_CODE;   // 返回状态码
	private String RETURN_MSG;   // 返回消息
	private String CURPAGE;   //当前页
	private String PAGECOUNT;  //总页数
	private String TOTAL;   //总数
	private String PAYAMOUNT;  //付款方式
	private String REFUNDAMOUNT;  //  修正???
}

PayCallBackEntity 实体类

/**
 * 建行支付回调实体类
 */
public class PayCallBackEntity {
	
	private String POSID; //商户柜台代码
	private String BRANCHID;//分行代码
	private String ORDERID; //定单号
	private String PAYMENT; //付款金额
	private String CURCODE;  //币种
	private String REMARK1;  //备注一
	private String REMARK2;  //备注二
	private String ACC_TYPE;  //账户类型  服务器通知中有此字段返回且参与验签
	private String SUCCESS;  //成功标志  成功-Y,失败-N
	private String TYPE;   //接口类型  分行业务人员在P2员工渠道后台设置防钓鱼的开关。 1.开关关闭时,无此字段返回且不参与验签 2.开关打开时,有此字段返回且参与验签。参数值为 1-防钓鱼接口

	private String REFERER;  //Referer信息  分行业务人员在P2员工渠道后台设置防钓鱼开关。 1.开关关闭时,无此字段返回且不参与验签。 2.开关打开时,有此字段返回且参与验签
	private String CLIENTIP;  //客户端IP  分行业务人员在P2员工渠道后台设置防钓鱼的开关。 1.开关关闭时,无此字段返回且不参与验签 2.开关打开时,有此字段返回且参与验签。参数值为 客户在建行系统中的IP
	private String ACCDATE;  //系统记账日期  商户登陆商户后台设置返回记账日期的开关 1.开关关闭时,无此字段返回且不参与验签。 2.开关打开时,有此字段返回且参与验签。参数值格式为YYYYMMDD(如20100907)。
	private String USRMSG; //支付账户信息  分行业务人员在P2员工渠道后台设置防钓鱼开关和返回账户信息的开关。 1.开关关闭时,无此字段返回且不参与验签。2.开关打开但支付失败时,无此字段返回且不参与验签。3.开关打开且支付成功时,有此字段返回且参与验签。无PAYTYPE返回时,参数值格式如下:“姓名|账号加密后的密文”。有PAYTYPE返回时,该参数值为空。
	private String USRINFO;   //客户加密信息   分行业务人员在P2员工渠道后台设置防钓鱼开关和客户信息加密返回的开关。 1.开关关闭时,无此字段返回且不参与验签
	private String PAYTYPE;  //支付方式   ALIPAY:支付宝 WEIXIN:微信 为空:建行龙支付 该字段有返回时参与验签,无此字段返回时不参与验签。
	private String SIGN;  //数字签名
}

httpclient工具类

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

public class HttpClientUtil {


	public static String httpReader(String url, String code){
		System.out.println("GetPage:"+url);
		
		HttpClient client = new HttpClient();
		GetMethod method = new GetMethod(url);
		
		String result = null;
		try {
			client.executeMethod(method);
			int status = method.getStatusCode();
			if (status == HttpStatus.SC_OK) {
				result = method.getResponseBodyAsString();
			} else {
				System.out.println("Method failed: " + method.getStatusLine());
			}
		} catch (HttpException e) {
			System.out.println("Please check your provided http address!");
			e.printStackTrace();
		} catch (IOException e) {
		
			e.printStackTrace();
		} finally{
			if(method!=null)method.releaseConnection();
			method = null;
			client = null;
		}
		return result;
	}
	
	public static String httpGet(String url,String code) {
		System.out.println("GetPage:"+url);
		String content = null;
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT,"Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090803 Fedora/3.5.2-2.fc11 Firefox/3.5.2");
		GetMethod method = new GetMethod(url);
		try {
			int statusCode = httpClient.executeMethod(method);
			System.out.println("httpClientUtils::statusCode="+statusCode);
			System.out.println(method.getStatusLine());
			content = new String(method.getResponseBody(), code);
			
		} catch (Exception e) {
			System.out.println("time out");
			e.printStackTrace();
		} finally {
			if(method!=null)method.releaseConnection();
			method = null;
			httpClient = null;
		}
		return content;
	}
	
	public static String httpPost(String url, Map paramMap, String code) {
		System.out.println("GetPage:"+url);
		String content = null;
		if (url == null || url.trim().length() == 0 || paramMap == null
				|| paramMap.isEmpty())
			return null;
		HttpClient httpClient = new HttpClient();

		httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT,"Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090803 Fedora/3.5.2-2.fc11 Firefox/3.5.2");//

		
		PostMethod method = new PostMethod(url);
		Iterator it = paramMap.keySet().iterator();
		

		while (it.hasNext()) {
			String key = it.next() + "";
			Object o = paramMap.get(key);
			if (o != null && o instanceof String) {
				method.addParameter(new NameValuePair(key, o.toString()));
			}
			if (o != null && o instanceof String[]) {
				String[] s = (String[]) o;
				if (s != null)
					for (int i = 0; i < s.length; i++) {
						method.addParameter(new NameValuePair(key, s[i]));
					}
			}
		}
		try {
			
			int statusCode = httpClient.executeMethod(method);
			
			System.out.println("httpClientUtils::statusCode="+statusCode);

			System.out.println(method.getStatusLine());
			content = new String(method.getResponseBody(), code);
			
		} catch (Exception e) {
			System.out.println("time out");
			e.printStackTrace();
		} finally {
			if(method!=null)method.releaseConnection();
			method = null;
			httpClient = null;
		}
		return content;

	}

	public static String httpPost(String url, Map paramMap) {

		return HttpClientUtil.httpPost(url, paramMap, "UTF-8");
	}
}

MD5工具类

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {

	public static String md5Str(String str) {
		if (str == null) return "";
		return md5Str(str, 0);
	}

	public static String md5Str(String str, int offset) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] b = str.getBytes("UTF8");
			md5.update(b, offset, b.length);
			return byteArrayToHexString(md5.digest());
		} catch (NoSuchAlgorithmException ex) {
			ex.printStackTrace();
			return null;
		} catch (UnsupportedEncodingException ex) {
			ex.printStackTrace();
			return null;
		}
	}

	/**
	 * @param b byte[]
	 * @return String
	 */
	public static String byteArrayToHexString(byte[] b) {
		String result = "";
		for (int i = 0; i < b.length; i++) {
			result += byteToHexString(b[i]);
		}
		return result;
	}

	private static String[] hexDigits =
			{
					"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b",
					"c", "d", "e", "f"};


	public static String byteToHexString(byte b) {
		int n = b;
		if (n < 0) {
			n = 256 + n;
		}
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}
}

QrURLDemo 实体类

/**
 * 建行无感支付实体类
 */
public class QrURLDemo {

	private String SUCCESS;
	private String PAYURL;
	private String QRURL;  //安卓点这个会直接跳到支付页面
}

QUERYORDER 实体类

public class QUERYORDER {
	private String MERCHANTID;  //商户代码
	private String BRANCHID;  //分行代码
	private String POSID;  //柜台号
	private String ORDERID;  //订单号
	private String ORDERDATE;  //订单支付的时间
	private String ACCDATE;  //访问日期记录
	private String AMOUNT;  //支付金额
	private String STATUSCODE;  //状态码
	private String STATUS; //交易状态  支付成功的话, 会返回 "成功"
	private String REFUND;  //退税???
	private String SIGN;  //签名
}
Magic丶Eliauk-
关注 关注
  • 17
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 53
    评论
java 对接农行支付相关业务(一)
人的一生就是在学习的道路上不断进步
05-28 858
java 对接农行支付相关业务,下单支付,退款,获取银行交易流水明细
Java实现建行聚合支付对接及其回调
weixin_44405455的博客
10-13 4931
系列文章目录 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于N
go建行支付异步通知验签处理
最新发布
lihua100862的博客
09-01 90
建行给的公钥是16进制公钥,如果拿来使用记得转换成一样。同样的还有sing签名串。
java 建行支付 Mac值生成 工具类 PayMd5.java
05-26
本工具类可用于对接支付时生成加密数据字段,方便同学们尽快完成任务。博主主要是用这个工具类生成的mac值用于对接建行支付
Java集成建行支付接口(详细)
dacheng_liu的博客
11-20 5382
Java集成建行支付接口(详细),持续更新!
Java-Spring Boot集成银联在线网关支付回调处理(银联扫码等方式支付
qq954724583的博客
02-23 3666
前言:最近开发银联支付功能,总结一下做个分享 官方API文档:https://open.unionpay.com/tjweb/api/dictionary?apiSvcId=448 银联测试地址:https://open.unionpay.com/tjweb/user/mchTest/index SKD和DEMO下载:https://open.unionpay.com/tjweb/acproduct/list?apiSvcId=448&index=4 银联支付流程: 1、准备工作:获取银联测试参数数
微信小程序云开发原生支持微信支付(官方云函数微信支付方法,无需服务器)
zjgo007的专栏
05-26 4871
使用云开发来实现相应的支付功能后,开发者无需关心证书、签名、微信支付服务器端文档,使用简单,代码较少,只需要调用相应的函数即可。 注意:当提交一次支付信息后,微信后台就会记录下当前订单号和对应的价格,即使未进行支付!再次提交相同订单号进行支付请求时,如果价格不一致,此时支付回调函数会返回“调用支付JSAPI缺少参数:total_fee”。解决方法为:修改订单号outTradeNo或者将价格与第一次提交时价格保持一致!
JAVA集成PC端银联支付(含代码和图文详解)
前者已逝,后者未至。
08-05 1286
准备 一、内网穿透工具: 我这里用花生壳做演示。 二、环境:(以银联支付目前的要求): 1、JDK1.6以上; 2、Tomcat6.0以上。 获取证书和代码 第一步: 注册登录银联支付:银联支付开放平台官网链接 第二步: 进入在线网关支付下载官方支付代码,操作如下: 第三步: 进入我要测试,下载相关证书 第四步: 修改/ACPSample_B2C/src/acp_sdk.properties文件中acpsdk.backUrl和acpsdk.front
Java对接iOS内购,回调地址验证.zip
04-28
主要是Java对接iOS内购,回调验证相关的方法, 真机测试的时候,一定要退出原来的账号,才能用沙盒测试账号,二次验证,请注意区分宏, 测试用沙盒验证,App Store审核的时候也使用的是沙盒购买,所以验证购买凭证的...
java实现企业微信回调配置案例
12-10
本案例将详细讲解如何使用Java实现企业微信的回调配置,并提供相关的工具代码示例。 1. **企业微信API介绍** 企业微信提供了丰富的API接口,包括但不限于用户管理、部门管理、消息推送等。回调配置主要是通过...
thinkPHP框架对接支付宝即时到账接口回调操作示例
12-19
关于支付宝即时收款接口的对接过程,很简单,也有很多人发过,我这里就不在啰嗦了,对接完成后,在线支付成功后的回调,相对来说,是个难点,,我重点分享下我的经验。 我在开发二代旅游CMS(http://www.erdaicms.com...
建行互联网被扫支付接口Socket商户验签jar包
06-21
1.1 环境准备 安装jdk1.4及以上版本,配置jdk相关环境。 1.2 网上支付商户验签包使用说明 商户验签包使用jdk1.4编译,可在jdk1.4及以上版本中运行; 将xml配置文件和jar包放在同一目录下。 1.3 参数配置说明 配置文件名称:ccbnetpayconfig.xml <?xml version="1.0" encoding="UTF-8"?> <!-- 中国建设银行商户通知验签配置文件 --> <ccbnetpayconfig> <!-- 通讯端口1024~65535之间未被使用的端口 --> <commport> <value>55533</value> </commport> <!-- 通讯端口1024~65535之间未被使用的端口 --> <maxconn> <value>5</value> </maxconn> <!-- 可按照不同的柜台号配置不同的公钥 --> <merpos> <!-- 商户柜台号 --> <posid>100001329</posid> <!-- 对应的
nodejs调用建行互联网银企被扫支付接口加密及验签Demo+java封装jar包
09-25
java源代码将建行互联网银企被扫支付接口java版加密及验签Demo 封装成jar包,方便nodejs调用。 1.将建行Java版加密Demo打包成jar包:CCBParam.jar。并将jar包放到服务器的相应文件夹下。 2.根据订单号、金额、付款码信息等拼接加密原串。 3.nodejs调用建行Java版加密Demo。参数为:flag,strSrcParas,PUBLICKEY,callback。 通过回调函数 得到加密串ccbParam。 nodejs调用java可以通过child_process模块中的spawn()函数实现。 var spawn = require('child_process').spawn;  nodejsJava.encryptccbParam=function(flag,param,pubKey,callback){//必须传入4个参数}    
springboot对接微信小程序支付以及回调详细代码
10-09
在本文中,我们将深入探讨如何使用SpringBoot框架与微信小程序进行支付对接,并实现支付回调功能。这个过程涉及多个步骤,包括配置、接口开发、微信支付API的调用以及回调处理。我们将按照描述中的"非常详细,完整...
[转]建行B2B支付回调参数乱码现象解析
weixin_33827965的博客
11-26 546
问题是这样出现的:在进行建行B2B网银在线支付时,建行回调时采用POST方式提交,编码方式为GBK,而我们的系统为ASP.NET,编码UTF-8。通过Request获取的参数是乱码。 题是这 解决办法:从InputStream解析,获取参数。具体代码如下: 1 IServiceProvider provi...
建行支付成功怎么触发回调_第三方支付接口超时响应、银行原生支付时可能出现的情况分析...
weixin_39946239的博客
12-08 1054
为什么出款一般都不是实时的?因为入款不是实时的,银行等第三方支付机构之间的资金清算有时间差,一般都是T+1才到账,如果想做到实时的出款就有垫资的风险,一般支付公司都不愿意垫资,但支付宝这个大型除外。对于第三方支付机构而言,银行通知了它支付成功,但是资金实际上还要T+1日才能结算到它的银行账户,也就是说目前只是承诺付款,但实际是在途资金尚未抵达,也就是信息流到了,资金流还没有过来。所以对于支付系统的...
ios h5版app 支付回调空白页面_iOS 接入建行支付说明
weixin_33320626的博客
12-27 1155
需求近期因为公司业务需求,需要接入建行支付,包含建行支付建行分期,因为分期只需要接入H5即可,龙支付需要H5和APP之间切换,故此将接入步骤详细记录下来,方便他人再次接入的时候,少入坑。(真的要吐槽下建行的文档,不够详细)。##配置信息1.首先需要在plist中进行scheme白名单配置,如下图:2.plist 的 NSAppTransportSecurity 字段添加相应的 NSExcep...
PHP 之建行支付-被扫(商家扫码客户二维码),扫码枪使用
weixin_42674576的博客
01-08 2034
PHP 之建行支付-被扫(商家扫码客户二维码),扫码枪使用
银行支付回调接口通知失败后,过段时间又通知成功
小布的世界
01-12 5825
支付订单状态一般情况下分为三大类,待支付,处理中,最终状态(成功或失败)。 待支付支付订单初始化创建 处理中:已经组装好支付数据或已经发送至支付机构,还未返回结果 最终状态:最终状态就是支付订单的最后状态,是不允许在修改了的。 我们是直连的工行,出现了这样一个现象,一个支付订单,回调了两次,第一次是失败提示说用户的账户余额不足,过了有9分钟,第二次通知说支付成功了。 场景分析:用户第一次支付,发
java小程序支付代码实现对接微信支付
07-25
对接微信支付,你需要使用微信支付提供的开发工具包(SDK)来实现支付功能。以下是一个简单示例,展示如何使用Java代码对接微信支付: ```java import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayConfig; import com.github.wxpay.sdk.WXPayConstants; import com.github.wxpay.sdk.WXPayUtil; import java.util.HashMap; import java.util.Map; public class WechatPaymentProgram { public static void main(String[] args) { // 商户号 String mchId = "your_mch_id"; // 商户密钥 String key = "your_mch_key"; // 应用ID String appId = "your_app_id"; // 回调URL String notifyUrl = "your_notify_url"; // 创建配置对象 WXPayConfig config = new WXPayConfig() { @Override public String getAppID() { return appId; } @Override public String getMchID() { return mchId; } @Override public String getKey() { return key; } }; // 创建WXPay对象 WXPay wxPay = new WXPay(config, WXPayConstants.SignType.MD5); // 创建订单参数 Map<String, String> data = new HashMap<>(); data.put("body", "商品描述"); data.put("out_trade_no", "商户订单号"); data.put("total_fee", "订单金额(单位为分)"); data.put("spbill_create_ip", "用户IP地址"); data.put("notify_url", notifyUrl); data.put("trade_type", "NATIVE"); // 扫码支付 try { // 调用统一下单接口 Map<String, String> resp = wxPay.unifiedOrder(data); // 判断返回结果 if ("SUCCESS".equals(resp.get("return_code")) && "SUCCESS".equals(resp.get("result_code"))) { String qrCodeUrl = resp.get("code_url"); // 获取支付二维码链接 System.out.println("请扫描以下二维码进行支付:" + qrCodeUrl); // TODO: 根据实际情况处理支付结果通知等逻辑 } else { System.out.println("下单失败:" + resp.get("return_msg")); } } catch (Exception e) { e.printStackTrace(); } } } ``` 在这个示例中,你需要替换代码中的 `your_mch_id`、`your_mch_key`、`your_app_id`和 `your_notify_url` 分别为你的微信商户号、商户密钥、应用ID和支付结果通知URL。然后根据实际情况填充订单参数,调用统一下单接口获取支付二维码链接,并输出给用户。最后根据微信支付结果通知的回调结果处理支付结果逻辑。 请注意,这只是一个简单的示例,并没有完整考虑所有的异常情况和业务逻辑。在实际应用中,你还需要处理用户扫码支付后的回调通知、订单查询、退款等功能。建议阅读微信支付官方文档和相关SDK的使用文档,了解完整的接口和流程。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • java实现对接建行支付及其回调 11052
  • mybatis 的like多条件模糊查询使用 1697
  • 【DataGrip 2022.2.2 设置tab页签字体颜色及其背景色】 1257
  • 解决spring boot 项目 tomcat 会启动两次的问题 1186
  • MySQL 计算时间差格式化为 X天X小时X分钟 725

分类专栏

  • Mysql 2篇
  • HashMap 1篇

最新评论

  • java实现对接建行支付及其回调

    ami_m0_47026818: 大佬,这个聚合收款二维码可以指定金额么

  • java实现对接建行支付及其回调

    J.P.C: 支付宝支付商户是直接到银行卡吗

  • java实现对接建行支付及其回调

    M7CCC: 大佬 通知成功后给建行应答具体给啥,文档里也没有写 表情包

  • 【DataGrip 2022.2.2 设置tab页签字体颜色及其背景色】

    人如其名都很棒!: 只改了背景色呀?字体色怎么改呢?

  • java实现对接建行支付及其回调

    ghgfgjjjn: 大佬 建行接口开发文档还有吗 这面网点业务员说找不到只给了个开发说明

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • MySQL 计算时间差格式化为 X天X小时X分钟
  • HashMap方法大赏
  • 【DataGrip 2022.2.2 设置tab页签字体颜色及其背景色】
2022年3篇
2020年5篇
2019年4篇

目录

目录

评论 53
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

PHP网站源码大鹏网站定制大浪网站制作龙岗网页制作大运SEO按天收费大芬SEO按效果付费横岗SEO按效果付费福永阿里店铺运营光明优化大浪标王沙井seo优化西乡SEO按天扣费民治网站改版松岗网站推广工具南联网络营销福田推广网站大芬品牌网站设计龙岗关键词按天收费惠州建设网站南澳关键词按天收费罗湖网络营销民治关键词按天扣费荷坳模板制作光明企业网站改版布吉网站优化按天收费丹竹头优化坂田优化大鹏企业网站建设同乐营销网站沙井至尊标王塘坑百搜标王歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化