工商银行聚合支付,java开发实现

a or 1=1     发表于  2021-08-20 11:52       490

最近有一个需求,微信公众号支付到工行账户中,因为做过支付的人都知道,一般的支付都是点对点的,比如支付宝支付就是支付到支付宝账户中,微信支付就是支付到微信账户中,那么微信,支付宝支付能支付到工行账户中吗?这个也是可以的,工行有一个API功能——工行聚合支付,这个可以实现这个需求

前提准备,与当地工行联系,这个要他们配合完成
前提准备:
1,在工行开放平台上注册一个账号,创建APP

2,创建账号后要获取API权限,要一步步审核下来,流程有点慢

3,审核流程走完后,可以获取到开发中需要的几个参数:网关公钥,APPID,数据签名校验的公钥,秘钥(公钥秘钥在工行提供的SDK中生成,SDK中有文档,这里我就不赘述了,生成后要将公钥给银行人员,让他们提交到服务器(因为我这的工行账户是他们帮助注册的)),商户号(当时与我联系的工行人员在开放平台上找了一上午,没找到,我也不知道这个商户号是啥,因为文档中对这个字段的介绍就是:“商户号”三字,简单不明了,看到这三个字,我第一想到的是微信支付有一个商户号,不知是不是这个商户号,后来与我联调的工行人员在他们卡部得到了这个“商户号”,那么得到商户号了,那么我们就可以开发了)
工行聚合支付SDK的使用,实现BizContent接口
//下载SDK,地址:https://open.icbc.com.cn/icbc/apip/docs_sdk&demo.html,图一//SDK下载后,我用的是Eclipse,因为SDK并非一个项目文件,需要自己在Eclipse中创建好一个项目,然后倒入文件系统,图二//他里面的各种Test就不用看了,因为这些Test的Demo都是不完整的,还是需要自己看API文档自己来。比如我们看到的有聚合支付的DEMO,如图三//接下来我们自己动手写了,packagecom.king.entity;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.Date;importcom.icbc.api.BizContent;/**
 * 
 * 
 * 
 *@Description*<p>
 *	说明:聚合支付,要实现BizContent,为什么呢,因为BizContent中似乎没有什么东西需要重写的呀,
 *	我的猜想是应为我们会用到他的AggregatePaymentRequestV2来生成请求Form,这个Form要求实现BizContent
 *</p>
 *@authorWDY
 *@date2020年1月20日 下午4:19:03
 *
 */public class TogetherPayment implements BizContent{/**
	 * 接口号,目前仅支持上送1.0.0.1
	 */private String interface_version;/**
	 * 商户号
	 */private String mer_id;/**
	 * 渠道商号;商户通过渠道商接入时必送。目前暂不支持上送。
	 */private String channel_id;/**
	 * 第三方应用ID;商户在微信公众号内接入时必送,上送微信分配的公众账号ID;商户通过支付宝生活号接入时必送,上送支付宝分配的应用ID。目前暂不支持上送
	 */private String tp_app_id;/**
	 * 第三方用户标识;商户在微信公众号/支付宝生活号内接入时必送,上送用户在商户appid下的唯一标识。 目前暂不支持上送
	 */private String tp_open_id;/**
	 * 商户订单号;需保证商户系统唯一
	 */private String out_trade_no;/**
	 * 交易类型。用于区分交易场景为线上支付还是线下支付,对应数据字典:
	 * OfflinePay-线下支付,
	 * OnlinePay-线上支付。商户需按实际交易场景上送,如上送错误可能影响后续交易的进行;比如线上支付场景,
	 * 上送OfflinePay-线下支付,使用微信支付时,微信会对实际交易场景进行检查,一旦发现不符,微信侧会拒绝对应交易请求
	 */private String tran_type;/**
	 * 交易提交时间, 格式为:YYYYMMDDHHmmss
	 */private String order_date;/**
	 * 交易过期时间,格式为:YYYYMMDDHHmmss。建议上送为order_date之后的五分钟或者固定为每晚11点这种形式
	 */private String end_time;/**
	 * 商品描述
	 */private String goods_body;/**
	 * 商品详情
	 */private String goods_detail;/**
	 * 附加数据。商户可上送定制信息(如商户会话ID、终端设备编号等),在支付结束后的支付结果通知报文中该字段原样返回,该字样可以在对账单中体现
	 */private String attach;/**
	 * 总金额(单位:分)
	 */private String order_amount;/**
	 * 终端ip
	 */private String spbill_create_ip;/**
	 * 分期期数。目前仅支持1-不分期
	 */private String install_times;/**
	 * 商家提示。目前暂无处理,后续可用于在交易页面回显给客户
	 */private String mer_hint;/**
	 * 支付成功回显页面。支付成功后,客户端引导跳转至该页面显示
	 */private String return_url;/**
	 * 支付方式限定;上送”no_credit“表示不支持信用卡支付;不上送或上送空表示无限制;上送“no_balance”表示仅支持银行卡支付(需要微信审批通过后可以接入)
	 */private String pay_limit;/**
	 * 支付结果通知地址;上送互联网可访问的完整URL地址(必须包含协议);应支持受理同一笔订单的多次通知场景
	 */private String notify_url;/**
	 * 通知类型,表示在交易处理完成后把交易结果通知商户的处理模式。 取值“HS”:在交易完成后将通知信息,主动发送给商户,发送地址为notify_url指定地址; 取值“AG”:在交易完成后不通知商户
	 */private String notify_type;/**
	 * 结果发送类型,通知方式为HS时有效。取值“0”:无论支付成功或者失败,银行都向商户发送交易通知信息;取值“1”,银行只向商户发送交易成功的通知信息
	 */private String result_type;         public static Stringfmt(Date date) {         return new SimpleDateFormat("YYYYMMDDHHmmss").format(date);	}        public static Dateparse(String date)           throws ParseException{returnnewSimpleDateFormat("YYYYMMDDHHmmss").parse(date);
	}        public String getInterface_version(){             if(interface_version==null) {               return"1.0.0.1";
		}        return this.interface_version;
	}public String getOrder_date(){     if(order_date==null)         {            return TogetherPayment.fmt(newDate());
	}        return   order_date;
   }public String getEnd_time()  throws ParseException{     if(end_time==null) {     long m =5*60*1000;      if(order_date!=null) {       return TogetherPayment.fmt(new Date(TogetherPayment.parse(order_date).getTime()+m));
       }else{       return TogetherPayment.fmt(new Date(System.currentTimeMillis()+m));
       }
    }   return   end_time;
  }	
}
使用工行提供的SDK来生成Form表单
package com.king.entity;import com.icbc.api.IcbcApiException;import com.icbc.api.IcbcConstants;import com.icbc.api.UiIcbcClient;import com.icbc.api.request.AggregatePaymentRequestV2;public class TestPay {// 1、网关公钥,这个网关公钥文档中有说,工行估计是先检查网关是否合法,如果网关都不合法,就没法进入系统的protected static final String APIGW_PUBLIC_KEY ="****";// 2、appid,注册应用时生成protected static final String APP_ID ="****";// 3、密钥对认证方式,公钥在API平台登记,此处为私钥protectedstaticfinalString MY_PRIVATE_KEY ="***";publicstaticvoidmain(String[] args)throwsIcbcApiException{// 签名类型为RSA2时,需传入appid,私钥和网关公钥,签名类型使用定值IcbcConstants.SIGN_TYPE_RSA2,其他参数使用缺省值String priKey ="****";// prikey为AES秘钥UiIcbcClient client =newUiIcbcClient(APP_ID, IcbcConstants.SIGN_TYPE_RSA2, MY_PRIVATE_KEY,"UTF-8","AES", priKey);

		AggregatePaymentRequestV2 request = new AggregatePaymentRequestV2();// 4、根据测试环境和生产环境替换相应ip和端口request.setServiceUrl("https://gw.open.icbc.com.cn/ui/aggregate/payment/request/V2");// 5、请对照接口文档用bizContent.setxxx()方法对业务上送数据进行赋值TogetherPayment b =newTogetherPayment();//商户号b.setMer_id("****");
		b.setAttach("工行破系统,谁开发的,给我站出来自行面壁十年!!!");
		b.setGoods_body("健康服务");
		b.setGoods_detail("{'good_name':'婴幼儿健康服务','good_id':'1001','good_num':'1'}");
		b.setInstall_times("1");
		b.setReturn_url("****");
		b.setResult_type("0");
		b.setNotify_url("****");
		b.setNotify_type("HS");
		
		b.setTp_app_id("gh_e88427cda7e0");
		b.setTp_open_id("o6lHr5qQj14isetvNT7wxcyy1-X8");
		
		b.setOrder_amount("10");
		b.setOut_trade_no("202000000004");
		b.setSpbill_create_ip("117.187.61.234");
		request.setBizContent(b);
		String r = client.buildPostForm(request);//这个人是一个自动提交的form表达,而且需要在微信或者支付宝中使用,工行系统会根据自动提交是http协议中的Referer来识别是微信还是支付宝System.out.println(r);

	}
}
最后的支付界面效果
//将生产的form表单在微信中渲染出来,因为是表单自动提交的,那么提交后,工行服务器处理完后会进行页面的重定向到输入金额的地方

本文转载于: https://www.boss-work.cn/particle/article/preview/4bb78ae748f04379851b3f1ead51b3e4