diff --git a/docs/doc/IJPay-Demo.html b/docs/doc/IJPay-Demo.html index d9dfd33b..77b0521d 100644 --- a/docs/doc/IJPay-Demo.html +++ b/docs/doc/IJPay-Demo.html @@ -888,7 +888,7 @@
特别说明:
68元
以上可以加个人微信畅聊30分钟,非诚勿扰。 169元
以上可以加入VIP交流群。 68元
以上可以加个人微信畅聊30分钟,非诚勿扰。 199元
以上可以一对一答疑。 javendev@126.com
TNW
极速开发微信公众号:https://gitee.com/javen205/TNWmica
工具集:https://gitee.com/596392912/micaAvue
一款基于 vue 可配置化的神奇框架:https://gitee.com/smallweigit/avuepig
宇宙最强微服务(架构师必备):https://gitee.com/log4j/pigSpringBlade
完整的线上解决方案(企业开发必备):https://gitee.com/smallc/SpringBlade微信 | -支付宝 | -
---|---|
- | - |
一对一交流 | -一对一 | -
- | - |
特别说明:
-68元
以上可以加个人微信畅聊30分钟,非诚勿扰。 169元
以上可以加入VIP交流群。 javendev@126.com
目前支持手机系统有:iOS(苹果)、Android(安卓)。
-https://docs.open.alipay.com/204
-参考博客 Android版-支付宝APP支付
- /**
- * APP支付
- * @param model
- * @param notifyUrl
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String startAppPay(AlipayTradeAppPayModel model, String notifyUrl) throws AlipayApiException{
- AlipayTradeAppPayResponse response = appPayToResponse(model,notifyUrl);
- return response.getBody();
- }
-
- /**
- * APP支付
- * https://doc.open.alipay.com/docs/doc.htm?treeId=54&articleId=106370&docType=1
- * @param model
- * @param notifyUrl
- * @return {AlipayTradeAppPayResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayTradeAppPayResponse appPayToResponse(AlipayTradeAppPayModel model, String notifyUrl) throws AlipayApiException{
- //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
- AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
- //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
- request.setBizModel(model);
- request.setNotifyUrl(notifyUrl);
- //这里和普通的接口调用不同,使用的是sdkExecute
- AlipayTradeAppPayResponse response = AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().sdkExecute(request);
- return response;
- }
-
- /**
- * APP支付
- * @param model
- * @param notifyUrl
- * @return {AlipayTradeAppPayResponse}
- * @throws {AlipayApiException}
- */
- @Deprecated
- public static AlipayTradeAppPayResponse appPay(AlipayTradeAppPayModel model, String notifyUrl) throws AlipayApiException{
- return appPayToResponse(model, notifyUrl);
- }
-
生成订单并返回唤起客户端支付的orderInfo
,具体实现如下:
/**
- * app支付
- */
- @RequestMapping(value = "/appPay")
- @ResponseBody
- public AjaxResult appPay() {
- try {
- AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
- model.setBody("我是测试数据-By Javen");
- model.setSubject("App支付测试-By Javen");
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- model.setTimeoutExpress("30m");
- model.setTotalAmount("0.01");
- model.setPassbackParams("callback params");
- model.setProductCode("QUICK_MSECURITY_PAY");
- String orderInfo = AliPayApi.startAppPay(model, aliPayBean.getDomain() + "/alipay/notify_url");
- result.success(orderInfo);
- } catch (AlipayApiException e) {
- e.printStackTrace();
- result.addError("system error:"+e.getMessage());
- }
- return result;
- }
-
- /**
- * app支付
- */
- public void appPay() {
- try {
- AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
- model.setBody("我是测试数据-By Javen");
- model.setSubject("App支付测试-By Javen");
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- model.setTimeoutExpress("30m");
- model.setTotalAmount("0.01");
- model.setPassbackParams("callback params");
- model.setProductCode("QUICK_MSECURITY_PAY");
- String orderInfo = AliPayApi.startAppPay(model, notify_domain + "/alipay/app_pay_notify");
- result.success(orderInfo);
- renderJson(result);
-
- } catch (AlipayApiException e) {
- e.printStackTrace();
- result.addError("system error");
- }
- }
-
官方App支付Android集成流程这里就不做过多解释了,下面我们来看看如何使用JPay快速接入Android APP支付。
-对微信App支付、支付宝App支付、银联App支付的二次封装,对外提供一个相对简单的接口以及支付结果的回调
- -GitHub:https://github.com/Javen205/JPay
-Gitee:http://gitee.com/Javen205/JPay
-使用方法
-Step 1. Add it in your root build.gradle at the end of repositories:
- allprojects {
- repositories {
- ...
- maven { url 'https://jitpack.io' }
- }
- }
-
Step 2. Add the dependency
-compile 'com.github.javen205.JPay:JPay:latest.release.here'
-
例如:版本号为0.0.4
compile 'com.github.javen205.JPay:JPay:0.0.4'
-
<uses-permission android:name="android.permission.INTERNET"/>
-<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-<uses-permission android:name="android.permission.READ_PHONE_STATE" />
-<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
application
节点添加如下类容
-
- <!-- 支付宝支付 -->
-
- <activity
- android:name="com.alipay.sdk.app.H5PayActivity"
- android:configChanges="orientation|keyboardHidden|navigation|screenSize"
- android:exported="false"
- android:screenOrientation="behind"
- android:windowSoftInputMode="adjustResize|stateHidden" >
- </activity>
- <activity
- android:name="com.alipay.sdk.app.H5AuthActivity"
- android:configChanges="orientation|keyboardHidden|navigation"
- android:exported="false"
- android:screenOrientation="behind"
- android:windowSoftInputMode="adjustResize|stateHidden" >
- </activity>
-
- <!-- 支付宝支付 end -->
-
如需开启测试模式只需要在OnCreate中添加如下代码。沙箱环境测试APP支付中请使用沙箱版钱包测试
-EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
--通过服务端接口获取到
-orderInfo
后唤起App客户端进行支付
JPay.getIntance(mContext).toPay(JPay.PayMode.ALIPAY, orderInfo, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
- Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayError(int error_code, String message) {
- Toast.makeText(mContext, "支付失败>"+error_code+" "+ message, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayCancel() {
- Toast.makeText(mContext, "取消了支付", Toast.LENGTH_SHORT).show();
- }
- });
-
或者
-Alipay.getInstance(mContext).startAliPay(orderInfo, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
-
- }
-
- @Override
- public void onPayError(int error_code, String message) {
-
- }
-
- @Override
- public void onPayCancel() {
-
- }
- });
-
-
- 参考文档 https://docs.open.alipay.com/200/105310
---温馨提示:支付宝有提供沙箱环境,测试时可以使用沙箱环境。
-
https://docs.open.alipay.com/200/105311
-沙箱环境APP只支持Android
-参考官方文档配置应用环境。
-这里我们不做支付宝生活号只做普通的支付 只需要设置接口的加密方式即可。生成RSA密钥 新建应用请务必使用2048位的密钥长度。在IJPay中也是使用的2048.
--- - -配置完成之后我们可以获得以下参考
--
-- 应用编号(appId)
-- 应用私钥(privateKey)
-- 应用公钥(publicKey)
-- 支付网关(serverUrl)
-
为PC网站,移动应用和H5场景提供收发现金红包支付通道的一款产品。主要应用于用户与用户互发红包和企业给用户发放营销红包。开发者可以应用于IM红包(钉钉红包),H5红包等。
-https://docs.open.alipay.com/301/106168
- /**
- * 红包无线支付接口
- * @param model
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String fundCouponOrderAppPay(AlipayFundCouponOrderAppPayModel model) throws AlipayApiException{
- AlipayFundCouponOrderAppPayResponse response = fundCouponOrderAppPayToResponse(model);
- return response.getBody();
- }
- /**
- * 红包无线支付接口
- * @param model
- * @return {AlipayFundCouponOrderAppPayResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundCouponOrderAppPayResponse fundCouponOrderAppPayToResponse(AlipayFundCouponOrderAppPayModel model) throws AlipayApiException{
- AlipayFundCouponOrderAppPayRequest request = new AlipayFundCouponOrderAppPayRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
-
- /**
- * 红包页面支付接口
- * @param model
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String fundCouponOrderPagePay(AlipayFundCouponOrderPagePayModel model) throws AlipayApiException{
- AlipayFundCouponOrderPagePayResponse response = fundCouponOrderPagePayToResponse(model);
- return response.getBody();
- }
- /**
- * 红包页面支付接口
- * @param model
- * @return {AlipayFundCouponOrderPagePayResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundCouponOrderPagePayResponse fundCouponOrderPagePayToResponse(AlipayFundCouponOrderPagePayModel model) throws AlipayApiException{
- AlipayFundCouponOrderPagePayRequest request = new AlipayFundCouponOrderPagePayRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
- /**
- * 红包协议支付接口
- * @param model
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String fundCouponOrderAgreementPay(AlipayFundCouponOrderAgreementPayModel model) throws AlipayApiException{
- AlipayFundCouponOrderAgreementPayResponse response = fundCouponOrderAgreementPayToResponse(model);
- return response.getBody();
- }
- /**
- * 红包协议支付接口
- * @param model
- * @return {AlipayFundCouponOrderAgreementPayResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundCouponOrderAgreementPayResponse fundCouponOrderAgreementPayToResponse(AlipayFundCouponOrderAgreementPayModel model) throws AlipayApiException{
- AlipayFundCouponOrderAgreementPayRequest request = new AlipayFundCouponOrderAgreementPayRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
- /**
- * 红包打款接口
- * @param model
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String fundCouponOrderDisburse(AlipayFundCouponOrderDisburseModel model) throws AlipayApiException{
- AlipayFundCouponOrderDisburseResponse response = fundCouponOrderDisburseToResponse(model);
- return response.getBody();
- }
- /**
- * 红包打款接口
- * @param model
- * @return {AlipayFundCouponOrderDisburseResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundCouponOrderDisburseResponse fundCouponOrderDisburseToResponse(AlipayFundCouponOrderDisburseModel model) throws AlipayApiException{
- AlipayFundCouponOrderDisburseRequest request = new AlipayFundCouponOrderDisburseRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
- /**
- * 红包退回接口
- * @param model
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String fundCouponOrderRefund(AlipayFundCouponOrderRefundModel model) throws AlipayApiException{
- AlipayFundCouponOrderRefundResponse response = fundCouponOrderRefundToResponse(model);
- return response.getBody();
- }
- /**
- * 红包退回接口
- * @param model
- * @return {AlipayFundCouponOrderRefundResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundCouponOrderRefundResponse fundCouponOrderRefundToResponse(AlipayFundCouponOrderRefundModel model) throws AlipayApiException{
- AlipayFundCouponOrderRefundRequest request = new AlipayFundCouponOrderRefundRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
- /**
- * 红包明细查询接口
- * @param model
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String fundCouponOperationQuery(AlipayFundCouponOperationQueryModel model) throws AlipayApiException{
- AlipayFundCouponOperationQueryResponse response = fundCouponOperationQueryToResponse(model);
- return response.getBody();
- }
- /**
- * 红包明细查询接口
- * @param model
- * @return {AlipayFundCouponOperationQueryResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundCouponOperationQueryResponse fundCouponOperationQueryToResponse(AlipayFundCouponOperationQueryModel model) throws AlipayApiException{
- AlipayFundCouponOperationQueryRequest request = new AlipayFundCouponOperationQueryRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
-
-- - -提示:沙箱环境无法测试红包接口必须使用线上应用测试。
-
在介绍IJPay中支付宝支付接口初始化之前先介绍一下支付宝服务端的SDK。因为IJPay支付宝支付接口是基于此SDK进行再次封装的。
-使用SDK分为以下几个步骤
-以下是支付宝SDK中WAP支付示例
-//实例化客户端
-AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
-//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.open.public.template.message.industry.modify
-AlipayOpenPublicTemplateMessageIndustryModifyRequest request = new AlipayOpenPublicTemplateMessageIndustryModifyRequest();
-//SDK已经封装掉了公共参数,这里只需要传入业务参数
-//此次只是参数展示,未进行字符串转义,实际情况下请转义
-request.setBizContent(" {" +
-" \"primary_industry_name\":\"IT科技/IT软件与服务\"," +
-" \"primary_industry_code\":\"10001/20102\"," +
-" \"secondary_industry_code\":\"10001/20102\"," +
-" \"secondary_industry_name\":\"IT科技/IT软件与服务\"" +
-" }");
-AlipayOpenPublicTemplateMessageIndustryModifyResponse response = alipayClient.execute(request);
-//调用成功,则处理业务逻辑
-if(response.isSuccess()){
- //.....
-}
-
--可以从JavaSDK集成示例中看到每次都要初始化客户端,需要查询对应的API以及复杂参数,接入步骤比较复杂。IJPay就是为了解决以上问题而诞生的。具体接入步骤后面会详细介绍,我们先来看看IJPay中支付宝接口的初始化。
-
IJPay中的支付宝支付支持多应用接入初始化客户端代码如下
-AliPayApiConfig aliPayApiConfig = AliPayApiConfig.New()
- .setAppId(app_id)
- .setAlipayPublicKey(alipay_public_key)
- .setCharset(charset)
- .setPrivateKey(private_key)
- .setServiceUrl(service_url)
- .setSignType(sign_type)
- .build();
-AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
-
当然支付接口中也不用每次都设置AliPayApiConfig
,可以通过AliPayApiConfigKit.getApiConfig(String appId)
获取AliPayApiConfig
//通过appId获取配置
-AliPayApiConfig aliPayApiConfig =AliPayApiConfigKit.getApiConfig(appId);
-
https://gitee.com/javen205/IJPay-Demo
-Demo中参数是配置在.properties
文件当中当然你也可以配置到数据库。 项目默认使用dev环境下的配置。 如果src/main/resources
没有dev
文件夹可以复制production
一份并修改为dev
,再修改dev
中相关的配置参数
多应用支持,JFinal完整版示例代码如下:
-/**
- * @Email javen205@126.com
- * @author Javen
- */
-public class AliPayApiInterceptor implements Interceptor {
- AlipayService alipayService = new AlipayService();
- AppService appService = new AppService();
- AjaxResult ajax = new AjaxResult();
-
- @Override
- public void intercept(Invocation inv) {
- Controller controller = inv.getController();
- String appId = controller.getPara("appId");
- if (StrKit.isBlank(appId)) {
- controller.renderJson(ajax.addError("应用的编号不能为空"));
- return;
- }
- //判断应用是否存在
- App app = appService.getAppByAppId(appId, 1);
- AliPayApiConfig aliPayApiConfig = null;
- if (app !=null) {
- // 通过应用的appId查询支付宝的配置
- Alipay alipay = alipayService.getAlipayByAppId(appId);
- if (alipay != null) {
- try {
- aliPayApiConfig = AliPayApiConfigKit.getApiConfig(alipay.getAppId());
- } catch (Exception e) {
- LogKit.error("实例化AliPayApiConfig...");
- // 如果Map中没有当前支付宝的实例就初始化并添加到Map中
- aliPayApiConfig = AliPayApiConfig.New()
- .setAppId(alipay.getAppId())
- .setAlipayPublicKey(alipay.getPublicKey())
- .setCharset(IJPayConsts.CHARSET)
- .setPrivateKey(alipay.getPrivateKey())
- .setServiceUrl(alipay.getServerUrl())
- .setSignType(IJPayConsts.SIGN_TYPE)
- .build();
- }
- }
- }
- if (aliPayApiConfig != null) {
- AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
- controller.setAttr("app", app);
- inv.invoke();
- } else {
- LogKit.error("aliPayApiConfig is null");
- controller.renderJson(ajax.addError("此应用暂未配置支付宝支付的参数"));
- }
- }
-}
-
-
- //获取支付宝POST过来反馈信息
-Map<String, String> params = AliPayApi.toMap(getRequest());
-//验证签名
-boolean verify_result = AlipaySignature.rsaCheckV1(params, alipay_public_key, charset,sign_type);
-
https://github.com/Javen205/IJPay-Demo
-public void notify_url() {
- try {
- // 获取支付宝POST过来反馈信息
- Map<String, String> params = AliPayApi.toMap(getRequest());
-
- for (Map.Entry<String, String> entry : params.entrySet()) {
- System.out.println(entry.getKey() + " = " + entry.getValue());
- }
-
- boolean verify_result = AlipaySignature.rsaCheckV1(params, alipay_public_key, charset,
- sign_type);
-
- if (verify_result) {// 验证成功
- // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
- System.out.println("notify_url 验证成功succcess");
- renderText("success");
- return;
- } else {
- System.out.println("notify_url 验证失败");
- // TODO
- renderText("failure");
- return;
- }
- } catch (AlipayApiException e) {
- e.printStackTrace();
- renderText("failure");
- }
- }
-
@RequestMapping(value = "/notify_url")
- @ResponseBody
- public String notify_url(HttpServletRequest request) {
- try {
- // 获取支付宝POST过来反馈信息
- Map<String, String> params = AliPayApi.toMap(request);
- for (Map.Entry<String, String> entry : params.entrySet()) {
- System.out.println(entry.getKey() + " = " + entry.getValue());
- }
-
- boolean verify_result = AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8",
- "RSA2");
-
- if (verify_result) {// 验证成功
- // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
- System.out.println("notify_url 验证成功succcess");
- return "success";
- } else {
- System.out.println("notify_url 验证失败");
- // TODO
- return "failure";
- }
- } catch (AlipayApiException e) {
- e.printStackTrace();
- return "failure";
- }
- }
-
-
- 沙箱环境下可以直接下载沙箱环境的APP进行测试,authCode
就是支付宝客户端付钱
中条码下的一窜数字。APP下载-沙箱工具
/**
- * 条形码支付、声波支付
- * @param model
- * @param notifyUrl
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String tradePay(AlipayTradePayModel model, String notifyUrl) throws AlipayApiException {
- AlipayTradePayResponse response = tradePayToResponse(model,notifyUrl);
- return response.getBody();
- }
- /**
- * 交易支付接口
- * 条形码支付、声波支付
- * @param model
- * @param notifyUrl
- * @return {AlipayTradePayResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayTradePayResponse tradePayToResponse(AlipayTradePayModel model, String notifyUrl) throws AlipayApiException{
- AlipayTradePayRequest request = new AlipayTradePayRequest();
- request.setBizModel(model);// 填充业务参数
- request.setNotifyUrl(notifyUrl);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request); // 通过AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient()调用API,获得对应的response类
- }
-
https://github.com/Javen205/IJPay-Demo
- /**
- * 条形码支付
- */
- public void tradePay() {
- String authCode = getPara("auth_code");
- String subject = "Javen 支付宝条形码支付测试";
- String totalAmount = "100";
- String notifyUrl = notify_domain + "/alipay/notify_url";
-
- AlipayTradePayModel model = new AlipayTradePayModel();
- model.setAuthCode(authCode);
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- model.setScene("bar_code");
- try {
- String resultStr = AliPayApi.tradePay(model,notifyUrl);
- renderText(resultStr);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
/**
- * 条形码支付
- */
- @RequestMapping(value ="/tradePay")
- @ResponseBody
- public String tradePay(@RequestParam("auth_code") String authCode) {
- String subject = "Javen 支付宝条形码支付测试";
- String totalAmount = "100";
- String notifyUrl = aliPayBean.getDomain() + "/alipay/notify_url";
-
- AlipayTradePayModel model = new AlipayTradePayModel();
- model.setAuthCode(authCode);
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- model.setScene("bar_code");
- try {
- return AliPayApi.tradePay(model,notifyUrl);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
-
- 具体流程这里就不详细介绍了,请参考之前写的一篇文章 支付宝支付-扫码支付详解
- /**
- * 统一收单线下交易预创建
- * 扫码支付
- * @param model
- * @param notifyUrl
- * @return {String}
- * @throws {AlipayApiException}
- */
- public static String tradePrecreatePay(AlipayTradePrecreateModel model, String notifyUrl) throws AlipayApiException{
- AlipayTradePrecreateResponse response = tradePrecreatePayToResponse(model,notifyUrl);
- return response.getBody();
- }
- /**
- * 扫码支付
- * @param model
- * @param notifyUrl
- * @return {AlipayTradePrecreateResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayTradePrecreateResponse tradePrecreatePayToResponse(AlipayTradePrecreateModel model, String notifyUrl) throws AlipayApiException{
- AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
- request.setBizModel(model);
- request.setNotifyUrl(notifyUrl);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
-
https://github.com/Javen205/IJPay-Demo
- /**
- * 扫码支付
- */
- @RequestMapping(value ="/tradePrecreatePay")
- @ResponseBody
- public String tradePrecreatePay() {
- String subject = "Javen 支付宝扫码支付测试";
- String totalAmount = "86";
- String storeId = "123";
- String notifyUrl = aliPayBean.getDomain() + "/alipay/notify_url";
-
- AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setStoreId(storeId);
- model.setTimeoutExpress("5m");
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- try {
- String resultStr = AliPayApi.tradePrecreatePay(model, notifyUrl);
- JSONObject jsonObject = JSONObject.parseObject(resultStr);
- return jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
-
- 沙箱环境下可以直接下载沙箱环境的APP进行测试,authCode
就是支付宝客户端付钱
中条码下的一窜数字。APP下载-沙箱工具
详见条码支付中的IJPay接口
-https://github.com/Javen205/IJPay-Demo
- /**
- * 声波支付
- */
- public void tradeWavePay() {
- String authCode = getPara("auth_code");
- String subject = "Javen 支付宝声波支付测试";
- String totalAmount = "100";
- String notifyUrl = notify_domain + "/alipay/notify_url";
-
- AlipayTradePayModel model = new AlipayTradePayModel();
- model.setAuthCode(authCode);
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- model.setScene("wave_code");
- try {
- String resultStr = AliPayApi.tradePay(model,notifyUrl);
- renderText(resultStr);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
/**
- * 声波支付
- */
- @RequestMapping(value ="/tradeWavePay")
- @ResponseBody
- public String tradeWavePay(@RequestParam("auth_code") String authCode) {
- String subject = "Javen 支付宝声波支付测试";
- String totalAmount = "100";
- String notifyUrl = aliPayBean.getDomain() + "/alipay/notify_url";
-
- AlipayTradePayModel model = new AlipayTradePayModel();
- model.setAuthCode(authCode);
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setOutTradeNo(StringUtils.getOutTradeNo());
- model.setScene("wave_code");
- try {
- return AliPayApi.tradePay(model,notifyUrl);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
-
- 电脑网站支付又称PC支付
-https://docs.open.alipay.com/270
- /**
- * 电脑网站支付(PC支付)
- * @param httpResponse
- * @param model
- * @param notifyUrl
- * @param returnUrl
- * @throws {AlipayApiException}
- * @throws IOException
- */
- public static void tradePage(HttpServletResponse httpResponse, AlipayTradePayModel model, String notifyUrl, String returnUrl) throws AlipayApiException, IOException{
- AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
- request.setBizModel(model);
- request.setNotifyUrl(notifyUrl);
- request.setReturnUrl(returnUrl);
- String form = AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().pageExecute(request).getBody();//调用SDK生成表单
- httpResponse.setContentType("text/html;charset=" + AliPayApiConfigKit.getAliPayApiConfig().getCharset());
- httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
- httpResponse.getWriter().flush();
- httpResponse.getWriter().close();
- }
-
https://github.com/Javen205/IJPay-Demo
- - /**
- * PC支付
- */
- @RequestMapping(value = "/pcPay")
- @ResponseBody
- public void pcPay(HttpServletResponse response){
- try {
- String totalAmount = "88.88";
- String outTradeNo =StringUtils.getOutTradeNo();
- log.info("pc outTradeNo>"+outTradeNo);
-
- String returnUrl = aliPayBean.getDomain() + "/alipay/return_url";
- String notifyUrl = aliPayBean.getDomain() + "/alipay/notify_url";
- AlipayTradePayModel model = new AlipayTradePayModel();
-
- model.setOutTradeNo(outTradeNo);
- model.setProductCode("FAST_INSTANT_TRADE_PAY");
- model.setTotalAmount(totalAmount);
- model.setSubject("Javen PC支付测试");
- model.setBody("Javen IJPay PC支付测试");
-
- AliPayApi.tradePage(response,model , notifyUrl, returnUrl);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
- /**
- * PC支付
- */
- public void pcPay(){
- try {
- String totalAmount = "88.88";
- String outTradeNo =StringUtils.getOutTradeNo();
- log.info("pc outTradeNo>"+outTradeNo);
-
- String returnUrl = notify_domain + "/alipay/return_url";
- String notifyUrl = notify_domain + "/alipay/notify_url";
- AlipayTradePayModel model = new AlipayTradePayModel();
-
- model.setOutTradeNo(outTradeNo);
- model.setProductCode("FAST_INSTANT_TRADE_PAY");
- model.setTotalAmount(totalAmount);
- model.setSubject("Javen PC支付测试");
- model.setBody("Javen IJPay PC支付测试");
- //花呗分期相关的设置
-
- /**
- * 测试环境不支持花呗分期的测试
- * hb_fq_num代表花呗分期数,仅支持传入3、6、12,其他期数暂不支持,传入会报错;
- * hb_fq_seller_percent代表卖家承担收费比例,商家承担手续费传入100,用户承担手续费传入0,仅支持传入100、0两种,其他比例暂不支持,传入会报错。
- */
-// ExtendParams extendParams = new ExtendParams();
-// extendParams.setHbFqNum("3");
-// extendParams.setHbFqSellerPercent("0");
-// model.setExtendParams(extendParams);
-
-
- AliPayApi.tradePage(getResponse(),model , notifyUrl, returnUrl);
- renderNull();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
-
- 支付宝提现又称单笔转账到支付宝账户
-https://docs.open.alipay.com/309/106235
- /**
- * 单笔转账到支付宝账户
- * @param model
- * @return {boolean}
- * @throws {AlipayApiException}
- */
- public static boolean transfer(AlipayFundTransToaccountTransferModel model) throws AlipayApiException{
- AlipayFundTransToaccountTransferResponse response = transferToResponse(model);
- String result = response.getBody();
- if (response.isSuccess()) {
- return true;
- } else {
- //调用查询接口查询数据
- JSONObject jsonObject = JSONObject.parseObject(result);
- String out_biz_no = jsonObject.getJSONObject("alipay_fund_trans_toaccount_transfer_response").getString("out_biz_no");
- AlipayFundTransOrderQueryModel queryModel = new AlipayFundTransOrderQueryModel();
- model.setOutBizNo(out_biz_no);
- boolean isSuccess = transferQuery(queryModel);
- if (isSuccess) {
- return true;
- }
- }
- return false;
- }
- /**
- * 单笔转账到支付宝账户
- * @param model
- * @return {AlipayFundTransToaccountTransferResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundTransToaccountTransferResponse transferToResponse(AlipayFundTransToaccountTransferModel model) throws AlipayApiException{
- AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
-
- /**
- * 转账查询接口
- * @param model
- * @return {boolean}
- * @throws {AlipayApiException}
- */
- public static boolean transferQuery(AlipayFundTransOrderQueryModel model) throws AlipayApiException{
- AlipayFundTransOrderQueryResponse response = transferQueryToResponse(model);
- if(response.isSuccess()){
- return true;
- }
- return false;
- }
- /**
- * 转账查询接口
- * @param model
- * @return {AlipayFundTransOrderQueryResponse}
- * @throws {AlipayApiException}
- */
- public static AlipayFundTransOrderQueryResponse transferQueryToResponse(AlipayFundTransOrderQueryModel model) throws AlipayApiException{
- AlipayFundTransOrderQueryRequest request = new AlipayFundTransOrderQueryRequest();
- request.setBizModel(model);
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().execute(request);
- }
-
https://gitee.com/javen205/IJPay-Demo -https://github.com/javen205/IJPay-Demo
- - /**
- * 单笔转账到支付宝账户
- */
- @RequestMapping(value = "/transfer")
- @ResponseBody
- public boolean transfer() {
- boolean isSuccess = false;
- String total_amount = "66";
- AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
- model.setOutBizNo(StringUtils.getOutTradeNo());
- model.setPayeeType("ALIPAY_LOGONID");
- model.setPayeeAccount("abpkvd0206@sandbox.com");
- model.setAmount(total_amount);
- model.setPayerShowName("测试退款");
- model.setPayerRealName("沙箱环境");
- model.setRemark("javen测试单笔转账到支付宝");
-
- try {
- isSuccess = AliPayApi.transfer(model);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return isSuccess;
- }
-
- /**
- * 单笔转账到支付宝账户
- */
- public void transfer() {
- boolean isSuccess = false;
- String total_amount = "66";
- AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
- model.setOutBizNo(StringUtils.getOutTradeNo());
- model.setPayeeType("ALIPAY_LOGONID");
- model.setPayeeAccount("abpkvd0206@sandbox.com");
- model.setAmount(total_amount);
- model.setPayerShowName("测试退款");
- model.setPayerRealName("沙箱环境");
- model.setRemark("javen测试单笔转账到支付宝");
-
- try {
- isSuccess = AliPayApi.transfer(model);
- } catch (Exception e) {
- e.printStackTrace();
- }
- renderJson(isSuccess);
- }
-
-
- 手机网站支付又称WAP支付
-https://docs.open.alipay.com/203
- /**
- * WAP支付
- * @param response
- * @param model
- * @param returnUrl
- * @param notifyUrl
- * @throws {AlipayApiException}
- * @throws IOException
- */
- public static void wapPay(HttpServletResponse response,AlipayTradeWapPayModel model,String returnUrl,String notifyUrl) throws AlipayApiException, IOException {
- String form = wapPayStr(response, model, returnUrl, notifyUrl);
- HttpServletResponse httpResponse = response;
- httpResponse.setContentType("text/html;charset=" + AliPayApiConfigKit.getAliPayApiConfig().getCharset());
- httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
- httpResponse.getWriter().flush();
- }
- /**
- * WAP支付
- * @param response
- * @param model
- * @param returnUrl
- * @param notifyUrl
- * @return {String}
- * @throws {AlipayApiException}
- * @throws IOException
- */
- public static String wapPayStr(HttpServletResponse response,AlipayTradeWapPayModel model,String returnUrl,String notifyUrl) throws AlipayApiException, IOException {
- AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();// 创建API对应的request
- alipayRequest.setReturnUrl(returnUrl);
- alipayRequest.setNotifyUrl(notifyUrl);// 在公共参数中设置回跳和通知地址
- alipayRequest.setBizModel(model);// 填充业务参数
- return AliPayApiConfigKit.getAliPayApiConfig().getAlipayClient().pageExecute(alipayRequest).getBody(); // 调用SDK生成表单
- }
-
https://github.com/Javen205/IJPay-Demo
- - @RequestMapping(value = "/wapPay")
- @ResponseBody
- public void wapPay(HttpServletResponse response) {
- String body = "我是测试数据-By Javen";
- String subject = "Javen Wap支付测试";
- String totalAmount = "1";
- String passbackParams = "1";
- String returnUrl = aliPayBean.getDomain() + "/alipay/return_url";
- String notifyUrl = aliPayBean.getDomain() + "/alipay/notify_url";
-
- AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
- model.setBody(body);
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setPassbackParams(passbackParams);
- String outTradeNo = StringUtils.getOutTradeNo();
- System.out.println("wap outTradeNo>"+outTradeNo);
- model.setOutTradeNo(outTradeNo);
- model.setProductCode("QUICK_WAP_PAY");
-
- try {
- AliPayApi.wapPay(response, model, returnUrl, notifyUrl);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Wap支付
- */
- public void wapPay() {
- String body = "我是测试数据-By Javen";
- String subject = "Javen Wap支付测试";
- String totalAmount = "1";
- String passbackParams = "1";
- String returnUrl = notify_domain + "/alipay/return_url";
- String notifyUrl = notify_domain + "/alipay/notify_url";
-
- AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
- model.setBody(body);
- model.setSubject(subject);
- model.setTotalAmount(totalAmount);
- model.setPassbackParams(passbackParams);
- String outTradeNo = StringUtils.getOutTradeNo();
- System.out.println("wap outTradeNo>"+outTradeNo);
- model.setOutTradeNo(outTradeNo);
- model.setProductCode("QUICK_WAP_PAY");
-
- try {
- AliPayApi.wapPay(getResponse(), model, returnUrl, notifyUrl);
- } catch (Exception e) {
- e.printStackTrace();
- }
- renderNull();
- }
-
--Demo中参数是配置在
-.properties
文件当中当然你也可以配置到数据库。 项目默认使用dev环境下的配置。 如果src/main/resources
没有dev
文件夹可以复制production
一份并修改为dev
,再修改dev
中相关的配置参数
需要商户APP的WebView处理alipays协议,具体实现可以参考手机网站支付唤起支付宝app -
-如何实现手机网站转Native支付?
-步骤一: 在接入方App中拦截H5的URL; -步骤二: 调用新增拦截+支付二合一接口(payInterceptorWithUrl...)进行URL拦截及支付转化。
-接口原型
-/**
- * 支付宝H5支付URL拦截器,完成拦截及支付方式转化
- *
- * @param h5PayUrl 待过滤拦截的 URL
- * @param isShowPayLoading 是否出现loading
- * @param callback 异步回调接口
- *
- * @return true:表示URL为支付宝支付URL,URL已经被拦截并支付转化;false:表示URL非支付宝支付URL;
- *
- */
- public synchronized boolean payInterceptorWithUrl(final String h5PayUrl, final boolean isShowPayLoading, final H5PayCallback callback)
-
-
-
- mweb_url
唤起微信客户端支付常见异常以及解决方案请参考博客-微信H5支付
-https://gitee.com/javen205/IJPay-Demo -https://github.com/javen205/IJPay-Demo
- - /**
- * 微信H5 支付
- * 注意:必须再web页面中发起支付且域名已添加到开发配置中
- */
- @RequestMapping(value ="/wapPay",method = {RequestMethod.POST,RequestMethod.GET})
- public void wapPay(HttpServletRequest request,HttpServletResponse response){
- String ip = IpKit.getRealIp(request);
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- H5ScencInfo sceneInfo = new H5ScencInfo();
-
- H5 h5_info = new H5();
- h5_info.setType("Wap");
- //此域名必须在商户平台--"产品中心"--"开发配置"中添加
-
-
- h5_info.setWap_url("https://pay.qq.com");
- h5_info.setWap_name("腾讯充值");
- sceneInfo.setH5_info(h5_info);
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay H5支付测试 -By Javen")
- .setBody("IJPay H5支付测试 -By Javen")
- .setSpbillCreateIp(ip)
- .setTotalFee("520")
- .setTradeType(TradeType.MWEB)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .setSceneInfo(h5_info.toString())
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
-log.info(xmlResult);
- Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = result.get("return_code");
- String return_msg = result.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- log.error("return_code>"+return_code+" return_msg>"+return_msg);
- throw new RuntimeException(return_msg);
- }
- String result_code = result.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- log.error("result_code>"+result_code+" return_msg>"+return_msg);
- throw new RuntimeException(return_msg);
- }
- // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
-
-
- String prepay_id = result.get("prepay_id");
- String mweb_url = result.get("mweb_url");
-
- log.info("prepay_id:"+prepay_id+" mweb_url:"+mweb_url);
- try {
- response.sendRedirect(mweb_url);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 微信H5 支付
- * 注意:必须再web页面中发起支付且域名已添加到开发配置中
- */
- public void wapPay(){
- String ip = IpKit.getRealIp(getRequest());
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- H5ScencInfo sceneInfo = new H5ScencInfo();
-
- H5 h5_info = new H5();
- h5_info.setType("Wap");
- //此域名必须在商户平台--"产品中心"--"开发配置"中添加
- h5_info.setWap_url("https://pay.qq.com");
- h5_info.setWap_name("腾讯充值");
- sceneInfo.setH5_info(h5_info);
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay H5支付测试 -By Javen")
- .setBody("IJPay H5支付测试 -By Javen")
- .setSpbillCreateIp(ip)
- .setTotalFee("520")
- .setTradeType(TradeType.MWEB)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .setSceneInfo(h5_info.toString())
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
-log.info(xmlResult);
- Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = result.get("return_code");
- String return_msg = result.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
- String result_code = result.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
- // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
-
- String prepay_id = result.get("prepay_id");
- String mweb_url = result.get("mweb_url");
-
- System.out.println("prepay_id:"+prepay_id+" mweb_url:"+mweb_url);
- redirect(mweb_url);
- }
-
-
- --普通商户模式与商户模式下支付接口URL都是相同的只是部分请求参数不同。IJPay中微信支付SDK初始化与支付宝初始化模式一致,请参考IJPay支付初始化。微信支付初始化是设置一些常量(appId、mch_id、partnerKey、PayMode等)到Map中避免后面接口请求时写过多冗代码。
-
public class WxPayApi {
- // 统一下单接口
- private static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
- // 订单查询
- private static final String ORDERQUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
- // 关闭订单
- private static final String CLOSEORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
- // 撤销订单
- private static final String REVERSE_URL = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
- // 申请退款
- private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
- // 查询退款
- private static final String REFUNDQUERY_URL = "https://api.mch.weixin.qq.com/pay/refundquery";
- // 下载对账单
- private static final String DOWNLOADBILLY_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
- // 交易保障
- private static final String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report";
- // 转换短链接
- private static final String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl";
- // 授权码查询openId接口
- private static final String AUTHCODETOOPENID_URL = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
- // 刷卡支付
- private static final String MICROPAY_URL = "https://api.mch.weixin.qq.com/pay/micropay";
- // 企业付款
- private static final String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
- // 查询企业付款
- private static final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo";
- // 申请签约
- private static final String ENTRUSTWEB_URL = "https://api.mch.weixin.qq.com/papay/entrustweb";
- // 支付中签约接口
- private static final String CONTRACTORDER_URL = "https://api.mch.weixin.qq.com/pay/contractorder";
- // 查询签约关系
- private static final String QUERYCONTRACT_URL = "https://api.mch.weixin.qq.com/papay/querycontract";
- // 申请扣款
- private static final String PAPPAYAPPLY_URL = "https://api.mch.weixin.qq.com/pay/pappayapply";
- // 申请解约
- private static final String DELETECONTRACT_URL = "https://api.mch.weixin.qq.com/papay/deletecontract";
- // 查询签约关系对账单
- private static final String CONTRACTBILL_URL = "https://api.mch.weixin.qq.com/papay/contractbill";
- // 代扣查询订单
- private static final String PAPORDERQUERYL_URL = "https://api.mch.weixin.qq.com/pay/paporderquery";
-
- // 获取沙箱秘钥
- private static final String GETSINGKEY = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey";
- // 统一下单接口
- private static final String UNIFIEDORDER_SANDBOXNEW_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder";
- // 刷卡支付
- private static final String MICROPAY_SANDBOXNEW_RUL = "https://api.mch.weixin.qq.com/sandboxnew/pay/micropay";
- // 订单查询
- private static final String ORDERQUERY_SANDBOXNEW_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery";
- // 申请退款
- private static final String REFUND_SANDBOXNEW_URL = "https://api.mch.weixin.qq.com/sandboxnew/secapi/pay/refund";
- // 查询退款
- private static final String REFUNDQUERY_SANDBOXNEW_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/refundquery";
- // 下载对账单
- private static final String DOWNLOADBILLY_SANDBOXNEW_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill";
-
- private WxPayApi() {
- }
-
- /**
- * 交易类型枚举 统一下单接口trade_type的传参可参考这里 JSAPI--公众号支付、小程序支付 NATIVE--原生扫码支付 APP--APP支付
- * MWEB--WAP支付 MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口
- */
- public static enum TradeType {
- JSAPI, NATIVE, APP, WAP, MICROPAY, MWEB ,PAP
- }
-
- /**
- * 获取验签秘钥API
- *
- * @param mch_id
- * 商户号
- * @param partnerKey
- * 密钥
- * @return {String}
- */
- public static String getsignkey(String mch_id, String partnerKey) {
- Map<String, String> map = new HashMap<String, String>();
- String nonce_str = String.valueOf(System.currentTimeMillis());
- map.put("mch_id", mch_id);
- map.put("nonce_str", nonce_str);
- map.put("sign", PaymentKit.createSign(map, partnerKey));
- return doPost(GETSINGKEY, map);
- }
-
- /**
- * 统一下单
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_1
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * @return {String}
- */
- public static String pushOrder(boolean isSandbox, Map<String, String> params) {
- if (isSandbox)
- return doPost(UNIFIEDORDER_SANDBOXNEW_URL, params);
- return doPost(UNIFIEDORDER_URL, params);
- }
-
- /**
- * 订单查询
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_2
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String orderQuery(boolean isSandbox, Map<String, String> params) {
- if (isSandbox)
- return doPost(ORDERQUERY_SANDBOXNEW_URL, params);
- return doPost(ORDERQUERY_URL, params);
- }
-
- /**
- * 关闭订单
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_3
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
- *
- * @param params
- * @return {String}
- */
- public static String closeOrder(Map<String, String> params) {
- return doPost(CLOSEORDER_URL, params);
- }
-
- /**
- * 撤销订单
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_11&index=3
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
- *
- * @param params
- * 请求参数
- * @param certPath
- * 证书文件目录
- * @param certPass
- * 证书密码
- * @return {String}
- */
- public static String orderReverse(Map<String, String> params, String certPath, String certPass) {
- return doPostSSL(REVERSE_URL, params, certPath, certPass);
- }
-
- /**
- * 申请退款
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_4
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * 请求参数
- * @param certPath
- * 证书文件目录
- * @param certPass
- * 证书密码
- * @return {String}
- */
- public static String orderRefund(boolean isSandbox, Map<String, String> params, String certPath, String certPass) {
- if (isSandbox)
- return doPostSSL(REFUND_SANDBOXNEW_URL, params, certPath, certPass);
- return doPostSSL(REFUND_URL, params, certPath, certPass);
- }
-
- /**
- * 查询退款
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_5
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String orderRefundQuery(boolean isSandbox, Map<String, String> params) {
- if (isSandbox)
- return doPost(REFUNDQUERY_SANDBOXNEW_URL, params);
- return doPost(REFUNDQUERY_URL, params);
- }
-
- /**
- * 下载对账单
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_6
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_6
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String downloadBill(boolean isSandbox, Map<String, String> params) {
- if (isSandbox)
- return doPost(DOWNLOADBILLY_SANDBOXNEW_URL, params);
- return doPost(DOWNLOADBILLY_URL, params);
- }
-
- /**
- * 交易保障
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_14&index=7
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_14&index=7
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String orderReport(Map<String, String> params) {
- return doPost(REPORT_URL, params);
- }
-
- /**
- * 转换短链接
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_9&index=8
- * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String toShortUrl(Map<String, String> params) {
- return doPost(SHORT_URL, params);
- }
-
- /**
- * 授权码查询openId
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_12&index=9
- * 商户模式接入文档:
- * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String authCodeToOpenid(Map<String, String> params) {
- return doPost(AUTHCODETOOPENID_URL, params);
- }
-
- /**
- * 刷卡支付
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_10&index=1
- * 商户模式接入文档:
- * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String micropay(boolean isSandbox, Map<String, String> params) {
- if (isSandbox)
- return WxPayApi.doPost(MICROPAY_SANDBOXNEW_RUL, params);
- return WxPayApi.doPost(MICROPAY_URL, params);
- }
-
- /**
- * 企业付款
- *
- * @param params
- * 请求参数
- * @param certPath
- * 证书文件目录
- * @param certPassword
- * 证书密码
- * @return {String}
- */
- public static String transfers(Map<String, String> params, String certPath, String certPassword) {
- return WxPayApi.doPostSSL(TRANSFERS_URL, params, certPath, certPassword);
- }
-
- /**
- * 查询企业付款
- *
- * @param params
- * 请求参数
- * @param certPath
- * 证书文件目录
- * @param certPassword
- * 证书密码
- * @return {String}
- */
- public static String getTransferInfo(Map<String, String> params, String certPath, String certPassword) {
- return WxPayApi.doPostSSL(GETTRANSFERINFO_URL, params, certPath, certPassword);
- }
-
- /**
- * 商户模式下 扫码模式一之生成二维码
- *
- * @param appid
- * @param mch_id
- * @param product_id
- * @param partnerKey
- * @param isToShortUrl
- * 是否转化为短连接
- * @return {String}
- */
- public static String getCodeUrl(String appid, String mch_id, String product_id, String partnerKey,
- boolean isToShortUrl) {
- String url = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX";
- String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
- String nonceStr = Long.toString(System.currentTimeMillis());
- Map<String, String> packageParams = new HashMap<String, String>();
- packageParams.put("appid", appid);
- packageParams.put("mch_id", mch_id);
- packageParams.put("product_id", product_id);
- packageParams.put("time_stamp", timeStamp);
- packageParams.put("nonce_str", nonceStr);
- String packageSign = PaymentKit.createSign(packageParams, partnerKey);
- String qrCodeUrl = PaymentKit.replace(url, "XXXXX", packageSign, appid, mch_id, product_id, timeStamp,
- nonceStr);
- if (isToShortUrl) {
- String shortResult = WxPayApi
- .toShortUrl(PaymentKit.buildShortUrlParasMap(appid, null, mch_id, null, qrCodeUrl, partnerKey));
- Map<String, String> shortMap = PaymentKit.xmlToMap(shortResult);
- String return_code = shortMap.get("return_code");
- if (PaymentKit.codeIsOK(return_code)) {
- String result_code = shortMap.get("result_code");
- if (PaymentKit.codeIsOK(result_code)) {
- qrCodeUrl = shortMap.get("short_url");
- }
- }
- }
-
- return qrCodeUrl;
- }
-
- /**
- * 申请签约 https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1&index=1
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String entrustweb(Map<String, String> params) {
- return doGet(ENTRUSTWEB_URL, params);
- }
-
- /**
- * 支付中签约 https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_13&index=2
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String contractorder(Map<String, String> params) {
- return doPost(CONTRACTORDER_URL, params);
- }
-
- /**
- * 查询签约关系 https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_2&index=3
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String querycontract(Map<String, String> params) {
- return doPost(QUERYCONTRACT_URL, params);
- }
-
- /**
- * 申请扣款
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String pappayapply(Map<String, String> params) {
- return doPost(PAPPAYAPPLY_URL, params);
- }
-
- /**
- * 申请解约
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String deletecontract(Map<String, String> params) {
- return doPost(DELETECONTRACT_URL, params);
- }
-
- /**
- * 查询签约关系对账单
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String contractbill(Map<String, String> params) {
- return doPost(CONTRACTBILL_URL, params);
- }
-
- /**
- * 代扣订单查询
- *
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String paporderquery(Map<String, String> params) {
- return doPost(PAPORDERQUERYL_URL, params);
- }
-
- public static String doGet(String url, Map<String, String> params) {
- return HttpUtils.get(url, params);
- }
-
- public static String doPost(String url, Map<String, String> params) {
- return HttpUtils.post(url, PaymentKit.toXml(params));
- }
-
- public static String doPostSSL(String url, Map<String, String> params, String certPath, String certPass) {
- return HttpUtils.postSSL(url, PaymentKit.toXml(params), certPath, certPass);
- }
-
-}
-
-
- --注:仿真测试环境中的商户号(父子商户号)需使用真实商户号。
-
/**
- * 刷卡支付
- * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_10&index=1
- * 商户模式接入文档:
- * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
- *
- * @param isSandbox
- * 是否是沙盒环境
- * @param params
- * 请求参数
- * @return {String}
- */
- public static String micropay(boolean isSandbox, Map<String, String> params) {
- if (isSandbox)
- return WxPayApi.doPost(MICROPAY_SANDBOXNEW_RUL, params);
- return WxPayApi.doPost(MICROPAY_URL, params);
- }
-
https://gitee.com/javen205/IJPay-Demo
- - /**
- * 刷卡支付
- * 已测试
- */
- public void micropay(){
- String auth_code = getPara("auth_code");
- String total_fee = getPara("total_fee");
-
- if (StrKit.isBlank(total_fee)) {
- ajax.addError("支付金额不能为空");
- renderJson(ajax);
- return;
- }
- if (StrKit.isBlank(auth_code)) {
- ajax.addError("auth_code参数错误");
- renderJson(ajax);
- return;
- }
-
- String ip = IpKit.getRealIp(getRequest());
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 测试 -By Javen")
- .setBody("IJPay 刷卡支付测试 -By Javen")
- .setSpbillCreateIp(ip)
- .setTotalFee(total_fee)
- .setAuthCode(auth_code)
- .setTradeType(TradeType.MICROPAY)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.micropay(false,params);
-
- //同步返回结果
- log.info("xmlResult:"+xmlResult);
-
- Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
- String return_code = result.get("return_code");
- String return_msg = result.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- //通讯失败
- String err_code = result.get("err_code");
- if (StrKit.notBlank(err_code)) {
- //用户支付中,需要输入密码
- if (err_code.equals("USERPAYING")) {
- //等待5秒后调用【查询订单API】https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
-
- }
- }
- log.info("提交刷卡支付失败>>"+xmlResult);
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
-
- String result_code = result.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- //支付失败
- //支付失败
- log.info("支付失败>>"+xmlResult);
- String err_code_des = result.get("err_code_des");
-
- ajax.addError(err_code_des);
- renderJson(ajax);
- return;
- }
-
- //支付成功
-
- renderText(xmlResult);
- }
-
- /**
- * 刷卡支付
- * 已测试
- */
- @RequestMapping(value = "/micropay",method= {RequestMethod.POST,RequestMethod.GET})
- @ResponseBody
- public AjaxResult micropay(HttpServletRequest request,HttpServletResponse response){
- String auth_code = request.getParameter("auth_code");
- String total_fee = request.getParameter("total_fee");
-
- if (StrKit.isBlank(total_fee)) {
- result.addError("支付金额不能为空");
- return result;
- }
- if (StrKit.isBlank(auth_code)) {
- result.addError("auth_code参数错误");
- return result;
- }
-
- String ip = IpKit.getRealIp(request);
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 测试 -By Javen")
- .setBody("IJPay 刷卡支付测试 -By Javen")
- .setSpbillCreateIp(ip)
- .setTotalFee(total_fee)
- .setAuthCode(auth_code)
- .setTradeType(TradeType.MICROPAY)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.micropay(false,params);
-
- //同步返回结果
-
-
- log.info("xmlResult:"+xmlResult);
-
- Map<String, String> resultMap = PaymentKit.xmlToMap(xmlResult);
- String return_code = resultMap.get("return_code");
- String return_msg = resultMap.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- //通讯失败
-
-
- String err_code = resultMap.get("err_code");
- if (StrKit.notBlank(err_code)) {
- //用户支付中,需要输入密码
-
-
- if (err_code.equals("USERPAYING")) {
- //等待5秒后调用【查询订单API】https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
-
-
-
- }
- }
- log.info("提交刷卡支付失败>>"+xmlResult);
- result.addError(return_msg);
- return result;
- }
-
- String result_code = resultMap.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- //支付失败
-
- log.info("支付失败>>"+xmlResult);
- String err_code_des = resultMap.get("err_code_des");
-
- result.addError(err_code_des);
- return result;
- }
- //支付成功
-
- result.success(xmlResult);
- return result;
- }
-
-
- --模式一开发前,商户必须在公众平台后台设置支付回调URL。URL实现的功能:接收用户扫码后微信支付系统回调的productid和openid;URL设置详见回调地址设置。
-
--模式二与模式一相比,流程更为简单,不依赖设置的回调支付URL。商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注意:code_url有效期为2小时,过期后扫码不能再发起支付。
-
模式一与模式二的区别
-二维码生成场景不同
---模式一是根据微信支付规定格式生成二维码展示给用户扫码,模式二是通过统一下单生成预付订单以及code_url其中code_url就是生成二维码的URL。
-
授权获取用户openId
---模式一不需要而模式二需要授权获取用户的openId
-
二维码有效期
---模式一永久有效而模式二有效期为2小时
-
模式一
----
-- 根据微信生成二维码规则生成二维码
-- 回调商户支付URL
-- 调用统一下单接口提交支付交易
-- 处理支付结果
-
模式二
----
-- 授权获取用户的openId
-- 调用统一下单接口生成预支付交易
-- 根据统一下单接口返回code_url生成二维码
-- 处理支付结果
-
--模式一
-
//根据生成二维码规则生成二维码URL
-String qrCodeUrl=WxPayApi.getCodeUrl(config.getAppId(), config.getMchId(),product_id, config.getPaternerKey(), true);
-//使用第三方工具生成二维码
-ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200, PathKit.getWebRootPath()+File.separator+name );
-
生成二维码具体实现
- /**
- * 扫码模式一之生成二维码
- *
- * @param appid
- * @param mch_id
- * @param product_id
- * @param partnerKey
- * @param isToShortUrl
- * 是否转化为短连接
- * @return {String}
- */
- public static String getCodeUrl(String appid, String mch_id, String product_id, String partnerKey,
- boolean isToShortUrl) {
- String url = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX";
- String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
- String nonceStr = Long.toString(System.currentTimeMillis());
- Map<String, String> packageParams = new HashMap<String, String>();
- packageParams.put("appid", appid);
- packageParams.put("mch_id", mch_id);
- packageParams.put("product_id", product_id);
- packageParams.put("time_stamp", timeStamp);
- packageParams.put("nonce_str", nonceStr);
- String packageSign = PaymentKit.createSign(packageParams, partnerKey);
- String qrCodeUrl = PaymentKit.replace(url, "XXXXX", packageSign, appid, mch_id, product_id, timeStamp,
- nonceStr);
- if (isToShortUrl) {
- String shortResult = WxPayApi
- .toShortUrl(PaymentKit.buildShortUrlParasMap(appid, null, mch_id, null, qrCodeUrl, partnerKey));
- Map<String, String> shortMap = PaymentKit.xmlToMap(shortResult);
- String return_code = shortMap.get("return_code");
- if (PaymentKit.codeIsOK(return_code)) {
- String result_code = shortMap.get("result_code");
- if (PaymentKit.codeIsOK(result_code)) {
- qrCodeUrl = shortMap.get("short_url");
- }
- }
- }
-
- return qrCodeUrl;
- }
-
--模式二
-
模式二生成二维码步骤请参考公用API
中的统一下单接口,示例代码请参考
下文代码示例
https://gitee.com/javen205/IJPay-Demo
---模式一
-
/**
- * 生成支付二维码(模式一)并在页面上显示
- */
- public void scanCode1(){
- try {
- String product_id = getPara("productId");
- if (StrKit.isBlank(product_id)) {
- ajax.addError("productId is null");
- renderJson(ajax);
- return;
- }
- WxPayApiConfig config = WxPayApiConfigKit.getWxPayApiConfig();
- //获取扫码支付(模式一)url
- String qrCodeUrl=WxPayApi.getCodeUrl(config.getAppId(), config.getMchId(),product_id, config.getPaternerKey(), true);
- log.info(qrCodeUrl);
- //生成二维码保存的路径
- String name = "payQRCode1.png";
- Boolean encode = ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
- PathKit.getWebRootPath()+File.separator+name );
- if (encode) {
- //在页面上显示
- ajax.success(name);
- renderJson(ajax);
- }
- } catch (Exception e) {
- ajax.addError("系统异常:"+e.getMessage());
- renderJson(ajax);
- e.printStackTrace();
- }
- }
-
/**
- * 扫码支付模式一回调
- * 已测试
- */
- public void wxpay(){
- try {
-
- String result = HttpKit.readData(getRequest());
- System.out.println("callBack_xml>>>"+result);
- /**
- * 获取返回的信息内容中各个参数的值
- */
- Map<String, String> map = PaymentKit.xmlToMap(result);
- for (String key : map.keySet()) {
- System.out.println("key= "+ key + " and value= " + map.get(key));
- }
-
- String appid=map.get("appid");
- String openid = map.get("openid");
- String mch_id = map.get("mch_id");
- String is_subscribe = map.get("is_subscribe");
- String nonce_str = map.get("nonce_str");
- String product_id = map.get("product_id");
- String sign = map.get("sign");
- Map<String, String> packageParams = new HashMap<String, String>();
- packageParams.put("appid", appid);
- packageParams.put("openid", openid);
- packageParams.put("mch_id",mch_id);
- packageParams.put("is_subscribe",is_subscribe);
- packageParams.put("nonce_str",nonce_str);
- packageParams.put("product_id", product_id);
-
- String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
- // 统一下单文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
-
-
- String ip = IpKit.getRealIp(getRequest());
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 扫码模式一测试 -By Javen")
- .setBody("IJPay 扫码模式一测试 -By Javen")
- .setOpenId(openid)
- .setSpbillCreateIp(ip)
- .setTotalFee("100")
- .setTradeType(TradeType.NATIVE)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
- log.info("prepay_xml>>>"+xmlResult);
-
- /**
- * 发送信息给微信服务器
- */
- Map<String, String> payResult = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = payResult.get("return_code");
- String result_code = payResult.get("result_code");
-
- if (StrKit.notBlank(return_code) && StrKit.notBlank(result_code) && return_code.equalsIgnoreCase("SUCCESS")&&result_code.equalsIgnoreCase("SUCCESS")) {
- // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
- String prepay_id = payResult.get("prepay_id");
-
- Map<String, String> prepayParams = new HashMap<String, String>();
- prepayParams.put("return_code", "SUCCESS");
- prepayParams.put("appId", appid);
- prepayParams.put("mch_id", mch_id);
- prepayParams.put("nonceStr", System.currentTimeMillis() + "");
- prepayParams.put("prepay_id", prepay_id);
- String prepaySign = null;
- if (sign.equals(packageSign)) {
- prepayParams.put("result_code", "SUCCESS");
- }else {
- prepayParams.put("result_code", "FAIL");
- prepayParams.put("err_code_des", "订单失效"); //result_code为FAIL时,添加该键值对,value值是微信告诉客户的信息
- }
- prepaySign = PaymentKit.createSign(prepayParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
- prepayParams.put("sign", prepaySign);
- String xml = PaymentKit.toXml(prepayParams);
- log.error(xml);
- renderText(xml);
-
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
--模式二
-
/**
- * 扫码支付模式二
- */
- public void scanCode2() {
- //String openId="o5NJx1dVRilQI6uUVSaBDuLnM3iM";
- String openId = (String) getSession().getAttribute("openId");
-
- String total_fee=getPara("total_fee");
-
- if (StrKit.isBlank(openId)) {
- ajax.addError("openId is null");
- renderJson(ajax);
- return;
- }
- if (StrKit.isBlank(total_fee)) {
- ajax.addError("支付金额不能为空");
- renderJson(ajax);
- return;
- }
-
- String ip = IpKit.getRealIp(getRequest());
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 测试 -By Javen")
- .setBody("IJPay 扫码支付2测试 -By Javen")
- .setOpenId(openId)
- .setSpbillCreateIp(ip)
- .setTotalFee(total_fee)
- .setTradeType(TradeType.NATIVE)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
-
-log.info(xmlResult);
- Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = result.get("return_code");
- String return_msg = result.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- System.out.println(return_msg);
- renderText(xmlResult);
- return;
- }
- String result_code = result.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- System.out.println(return_msg);
- renderText(xmlResult);
- return;
- }
- //生成预付订单success
-
- String qrCodeUrl = result.get("code_url");
- String name = "payQRCode2.png";
-
- Boolean encode = ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
- PathKit.getWebRootPath()+File.separator+name);
- if (encode) {
-// renderQrCode(qrCodeUrl, 200, 200);
- //在页面上显示
- ajax.success(name);
- renderJson(ajax);
- }
- }
-
-
- --建议支付目录设置到支付URL上一级目录
-
开发步骤-官方介绍文档
-授权获取用户信息官方文档 -微信公众号开发之授权获取用户信息
-调用统一下单接口后生成预付订单 参考公用API
对生成的预付订单进行二次签名再使用JS API唤起支付 参考公用API
JS部分代码参考-IJPay-Demo
-https://gitee.com/javen205/IJPay-Demo
- - /**
- * 公众号支付
- */
- @RequestMapping(value ="/webPay",method = {RequestMethod.POST,RequestMethod.GET})
- @ResponseBody
- public AjaxResult webPay(HttpServletRequest request,HttpServletResponse response,
- @RequestParam("total_fee") String total_fee) {
- // openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
-
- String openId = (String) request.getSession().getAttribute("openId");
-
- if (StrKit.isBlank(openId)) {
- result.addError("openId is null");
- return result;
- }
- if (StrKit.isBlank(total_fee)) {
- result.addError("请输入数字金额");
- return result;
- }
-
- String ip = IpKit.getRealIp(request);
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 公众号支付测试 -By Javen")
- .setBody("IJPay 公众号支付测试 -By Javen")
- .setOpenId(openId)
- .setSpbillCreateIp(ip)
- .setTotalFee(total_fee)
- .setTradeType(TradeType.JSAPI)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
-log.info(xmlResult);
- Map<String, String> resultMap = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = resultMap.get("return_code");
- String return_msg = resultMap.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- result.addError(return_msg);
- return result;
- }
- String result_code = resultMap.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- result.addError(return_msg);
- return result;
- }
- // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
-
-
- String prepay_id = resultMap.get("prepay_id");
-
- Map<String, String> packageParams = PaymentKit.prepayIdCreateSign(prepay_id);
-
- String jsonStr = JSON.toJSONString(packageParams);
- result.success(jsonStr);
- return result;
- }
-
-public void webPay() {
-
- // openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
- String openId = (String) getSession().getAttribute("openId");
-
- String total_fee=getPara("total_fee");
-
- if (StrKit.isBlank(openId)) {
- ajax.addError("openId is null");
- renderJson(ajax);
- return;
- }
- if (StrKit.isBlank(total_fee)) {
- ajax.addError("请输入数字金额");
- renderJson(ajax);
- return;
- }
-
- String ip = IpKit.getRealIp(getRequest());
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 公众号支付测试 -By Javen")
- .setBody("IJPay 公众号支付测试 -By Javen")
- .setOpenId(openId)
- .setSpbillCreateIp(ip)
- .setTotalFee(total_fee)
- .setTradeType(TradeType.JSAPI)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
-log.info(xmlResult);
- Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = result.get("return_code");
- String return_msg = result.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
- String result_code = result.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
- // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
- String prepay_id = result.get("prepay_id");
-
- Map<String, String> packageParams = PaymentKit.prepayIdCreateSign(prepay_id);
-
- String jsonStr = JsonKit.toJson(packageParams);
- ajax.success(jsonStr);
- renderJson(ajax);
- }
-
-
- 请求微信接口时将Map参数转化为xml
-PaymentKit.toXml(Map<String, String> params)
-
将微信接口响应的结果xml转化为Map
-PaymentKit.xmlToMap(xml);
-
IpKit.getRealIp(HttpServletRequest request);
-
PaymentKit.createSign(Map<String, String> params, String partnerKey);
-
params
为加密的参数,partnerKey
为商户平台设置的API密钥key
--key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
-
WxPayApi.pushOrder(boolean isSandbox, Map<String, String> params);
-
--代码示例参考具体支付方式中的代码
-
公众号支付二次签名-微信内H5调起支付
小程序支付二次签名-小程序调起支付API
PaymentKit.prepayIdCreateSign(String prepay_id)
-
/**
- * 预付订单再次签名
- * @param prepay_id
- * @return <Map<String, String>>
- */
- public static Map<String, String> prepayIdCreateSign(String prepay_id) {
- Map<String, String> packageParams = new HashMap<String, String>();
- packageParams.put("appId", WxPayApiConfigKit.getWxPayApiConfig().getAppId());
- packageParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
- packageParams.put("nonceStr", String.valueOf(System.currentTimeMillis()));
- packageParams.put("package", "prepay_id=" + prepay_id);
- packageParams.put("signType", "MD5");
- String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
- packageParams.put("paySign", packageSign);
- return packageParams;
- }
-
APP支付二次签名-调起支付
- /**
- * 预付订单再次签名
- * @param prepay_id
- * @return <Map<String, String>>
- */
- public static Map<String, String> prepayIdCreateSignByApp(String prepay_id) {
- Map<String, String> packageParams = new HashMap<String, String>();
- packageParams.put("appid", WxPayApiConfigKit.getWxPayApiConfig().getAppId());
- packageParams.put("partnerid", WxPayApiConfigKit.getWxPayApiConfig().getMchId());
- packageParams.put("prepayid", prepay_id);
- packageParams.put("package", "Sign=WXPay");
- packageParams.put("noncestr", System.currentTimeMillis() + "");
- packageParams.put("timestamp", System.currentTimeMillis() / 1000 + "");
- String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
- packageParams.put("sign", packageSign);
- return packageParams;
- }
-
PaymentKit.verifyNotify(Map<String, String> params, String paternerKey)
-
params
为回调的xml转Map参数,partnerKey
为商户平台设置的API密钥key
-- - -key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
-
公用API
)公用API
)服务端异步通知
)https://gitee.com/javen205/IJPay-Demo -https://github.com/javen205/IJPay-Demo
-
- /**
- * 微信小程序支付
- */
- public void aappPay(){
-
- String ip = IpKit.getRealIp(getRequest());
- if (StrKit.isBlank(ip)) {
- ip = "127.0.0.1";
- }
-
- Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
- .setAttach("IJPay 测试 -By Javen")
- .setBody("IJPay 小程序支付测试 -By Javen")
- .setSpbillCreateIp(ip)
- .setTotalFee("100")
- .setTradeType(WxPayApi.TradeType.JSAPI)
- .setNotifyUrl(notify_url)
- .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
- .build();
-
- String xmlResult = WxPayApi.pushOrder(false,params);
-
-log.info(xmlResult);
- Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
-
- String return_code = result.get("return_code");
- String return_msg = result.get("return_msg");
- if (!PaymentKit.codeIsOK(return_code)) {
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
- String result_code = result.get("result_code");
- if (!PaymentKit.codeIsOK(result_code)) {
- ajax.addError(return_msg);
- renderJson(ajax);
- return;
- }
- // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
- String prepay_id = result.get("prepay_id");
- //封装调起微信支付的参数https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5
- Map<String, String> packageParams = new HashMap<String, String>();
- packageParams.put("appId", WxPayApiConfigKit.getWxPayApiConfig().getAppId());
- packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
- packageParams.put("nonceStr", System.currentTimeMillis() + "");
- packageParams.put("package", "prepay_id="+prepay_id);
- packageParams.put("signType", "MD5");
- String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
- packageParams.put("paySign", packageSign);
-
- String jsonStr = JsonKit.toJson(packageParams);
-log.info("最新返回小程序支付的参数:"+jsonStr);
- renderJson(jsonStr);
- }
-
-
- 参考 公用API
https://github.com/Javen205/IJPay-Demo
- - @RequestMapping(value = "/pay_notify",method={RequestMethod.POST,RequestMethod.GET})
- @ResponseBody
- public String pay_notify(HttpServletRequest request) {
- // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
- String xmlMsg = HttpKit.readData(request);
- System.out.println("支付通知="+xmlMsg);
- Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
-// String appid = params.get("appid");
-// //商户号
-// String mch_id = params.get("mch_id");
- String result_code = params.get("result_code");
-// String openId = params.get("openid");
-// //交易类型
-// String trade_type = params.get("trade_type");
-// //付款银行
-// String bank_type = params.get("bank_type");
-// // 总金额
-// String total_fee = params.get("total_fee");
-// //现金支付金额
-// String cash_fee = params.get("cash_fee");
-// // 微信支付订单号
-// String transaction_id = params.get("transaction_id");
-// // 商户订单号
-// String out_trade_no = params.get("out_trade_no");
-// // 支付完成时间,格式为yyyyMMddHHmmss
-// String time_end = params.get("time_end");
- /////////////////////////////以下是附加参数///////////////////////////////////
-
- String attach = params.get("attach");
-// String fee_type = params.get("fee_type");
-// String is_subscribe = params.get("is_subscribe");
-// String err_code = params.get("err_code");
-// String err_code_des = params.get("err_code_des");
- // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
- // 避免已经成功、关闭、退款的订单被再次更新
-// Order order = Order.dao.getOrderByTransactionId(transaction_id);
-// if (order==null) {
- if(PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())){
- if (("SUCCESS").equals(result_code)) {
- //更新订单信息
- log.warn("更新订单信息:"+attach);
- //发送通知等
- Map<String, String> xml = new HashMap<String, String>();
- xml.put("return_code", "SUCCESS");
- xml.put("return_msg", "OK");
- return PaymentKit.toXml(xml);
- }
- }
-// }
- return null;
- }
-
-public void pay_notify() {
- //获取所有的参数
- StringBuffer sbf=new StringBuffer();
-
- Enumeration<String> en=getParaNames();
- while (en.hasMoreElements()) {
- Object o= en.nextElement();
- sbf.append(o.toString()+"="+getPara(o.toString()));
- }
-
- log.error("支付通知参数:"+sbf.toString());
-
- // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
- String xmlMsg = HttpKit.readData(getRequest());
- System.out.println("支付通知="+xmlMsg);
- Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
-
-// String appid = params.get("appid");
-// //商户号
-// String mch_id = params.get("mch_id");
- String result_code = params.get("result_code");
-// String openId = params.get("openid");
-// //交易类型
-// String trade_type = params.get("trade_type");
-// //付款银行
-// String bank_type = params.get("bank_type");
-// // 总金额
-// String total_fee = params.get("total_fee");
-// //现金支付金额
-// String cash_fee = params.get("cash_fee");
-// // 微信支付订单号
-// String transaction_id = params.get("transaction_id");
-// // 商户订单号
-// String out_trade_no = params.get("out_trade_no");
-// // 支付完成时间,格式为yyyyMMddHHmmss
-// String time_end = params.get("time_end");
-
- /////////////////////////////以下是附加参数///////////////////////////////////
-
- String attach = params.get("attach");
-// String fee_type = params.get("fee_type");
-// String is_subscribe = params.get("is_subscribe");
-// String err_code = params.get("err_code");
-// String err_code_des = params.get("err_code_des");
-
-
- // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
- // 避免已经成功、关闭、退款的订单被再次更新
-// Order order = Order.dao.getOrderByTransactionId(transaction_id);
-// if (order==null) {
- if(PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())){
- if (("SUCCESS").equals(result_code)) {
- //更新订单信息
- log.warn("更新订单信息:"+attach);
-
- //发送通知等
-
- Map<String, String> xml = new HashMap<String, String>();
- xml.put("return_code", "SUCCESS");
- xml.put("return_msg", "OK");
- renderText(PaymentKit.toXml(xml));
- return;
- }
- }
-// }
- renderText("");
- }
-
-
- 🔥 IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口.不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。
-GitHub:https://github.com/Javen205/IJPay
-Gitee:http://gitee.com/Javen205/IJPay
-目前IJPay Demo 提供两个版本 JFinal版本以及Spring Boot版本
-GitHub:https://github.com/Javen205/IJPay-Demo
-Gitee:https://gitee.com/Javen205/IJPay-Demo
-欢迎Start支持项目发展:)
- -特别说明:
-🔥对微信App支付、支付宝App支付、银联APP支付的二次封装,对外提供一个相对简单的接口以及支付结果的回调。
- -GitHub:https://github.com/Javen205/JPay
-Gitee:http://gitee.com/Javen205/JPay
- -联系方式
- -使用方法
-Step 1. Add it in your root build.gradle at the end of repositories:
- allprojects {
- repositories {
- ...
- maven { url 'https://jitpack.io' }
- }
- }
-
Step 2. Add the dependency
-compile 'com.github.javen205.JPay:JPay:latest.release.here'
-
例如:版本号为0.0.4
compile 'com.github.javen205.JPay:JPay:0.0.4'
-
<uses-permission android:name="android.permission.INTERNET"/>
-<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-<uses-permission android:name="android.permission.READ_PHONE_STATE" />
-<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-<uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD" />
-<uses-permission android:name="android.permission.NFC" />
-<uses-feature android:name="android.hardware.nfc.hce"/>
-
application
节点添加如下类容
<!-- 微信支付 -->
- <activity
- android:name="com.jpay.weixin.WXPayEntryActivity"
- android:configChanges="orientation|keyboardHidden|navigation|screenSize"
- android:launchMode="singleTop"
- android:theme="@android:style/Theme.Translucent.NoTitleBar" />
- <activity-alias
- android:name=".wxapi.WXPayEntryActivity"
- android:exported="true"
- android:targetActivity="com.jpay.weixin.WXPayEntryActivity" />
- <!-- 微信支付 end -->
-
-
- <!-- 支付宝支付 -->
-
- <activity
- android:name="com.alipay.sdk.app.H5PayActivity"
- android:configChanges="orientation|keyboardHidden|navigation|screenSize"
- android:exported="false"
- android:screenOrientation="behind"
- android:windowSoftInputMode="adjustResize|stateHidden" >
- </activity>
- <activity
- android:name="com.alipay.sdk.app.H5AuthActivity"
- android:configChanges="orientation|keyboardHidden|navigation"
- android:exported="false"
- android:screenOrientation="behind"
- android:windowSoftInputMode="adjustResize|stateHidden" >
- </activity>
-
- <!-- 支付宝支付 end -->
-
- <!-- 银联支付 -->
- <uses-library android:name="org.simalliance.openmobileapi" android:required="false"/>
- <activity
- android:name="com.unionpay.uppay.PayActivity"
- android:screenOrientation="portrait"
- android:configChanges="orientation|keyboardHidden"
- android:excludeFromRecents="true"
- android:windowSoftInputMode="adjustResize"/>
- <activity
- android:name="com.unionpay.UPPayWapActivity"
- android:configChanges="orientation|keyboardHidden|fontScale"
- android:screenOrientation="portrait"
- android:windowSoftInputMode="adjustResize" >
- </activity>
- <!-- 银联支付 end -->
-
JPay.getIntance(mContext).toPay(JPay.PayMode.WXPAY, payParameters, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
- Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show()
- }
-
- @Override
- public void onPayError(int error_code, String message) {
- Toast.makeText(mContext, "支付失败>"+error_code+" "+ message, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayCancel() {
- Toast.makeText(mContext, "取消了支付", Toast.LENGTH_SHORT).show();
- }
- });
-
payParameters
为JSON字符串格式如下:
{
- "appId": "",
- "partnerId": "",
- "prepayId": "",
- "sign": "",
- "nonceStr" : "",
- "timeStamp": ""
-}
-
或者
-JPay.getIntance(mContext).toWxPay(appId, partnerId, prepayId, nonceStr, timeStamp, sign, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
- Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayError(int error_code, String message) {
- Toast.makeText(mContext, "支付失败>"+error_code+" "+ message, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayCancel() {
- Toast.makeText(mContext, "取消了支付", Toast.LENGTH_SHORT).show();
- }
- });
-
JPay.getIntance(mContext).toPay(JPay.PayMode.ALIPAY, orderInfo, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
- Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayError(int error_code, String message) {
- Toast.makeText(mContext, "支付失败>"+error_code+" "+ message, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayCancel() {
- Toast.makeText(mContext, "取消了支付", Toast.LENGTH_SHORT).show();
- }
- });
-
或者
-Alipay.getInstance(mContext).startAliPay(orderInfo, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
-
- }
-
- @Override
- public void onPayError(int error_code, String message) {
-
- }
-
- @Override
- public void onPayCancel() {
-
- }
- });
-
步骤一 调起银联手机控件支付
-JPay.getIntance(mContext).toUUPay("01",tn, new JPay.JPayListener() {
- @Override
- public void onPaySuccess() {
- Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayError(int error_code, String message) {
- Toast.makeText(mContext, "支付失败>" + error_code + " " + message, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onPayCancel() {
- Toast.makeText(mContext, "取消了支付", Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onUUPay(String dataOrg, String sign, String mode) {
- Toast.makeText(mContext, "支付成功>需要后台查询订单确认>"+dataOrg+" "+mode, Toast.LENGTH_SHORT).show();
- }
- });
-
--说明 -第一个参数
-mode
"00" - 启动银联正式环境 "01" - 连接银联测试环境 -第二个参数tn
后台获取下单交易的流水号 -第三方参数是JPay
封装的客户端结果的回调,需要在onUUPay
中自行去后台查询订单的最终支付状态
步骤二 设置回调
-@Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- try {
- UPPay.getInstance(this).onUUPayResult(data);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
--appId以及相关的key我们都从服务端获取
-
AndroidManifest.xml
的包名修改为申请应用的包名build.gradle
的 applicationId
修改为申请应用的包名--将key复制到项目的根目录(app)中并修改
-buildTypes
配置如下
signingConfigs {
- release {
- storeFile file("wxkey")
- storePassword '123456'
- keyAlias '1'
- keyPassword '123456'
- }
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- debug {
- signingConfig signingConfigs.release
- }
- }
-
IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口
-微信、支付宝APP支付详细介绍参考资料 博客地址
-10分钟搭建属于自己的ngork服务器,实现内网穿透 -Android版-微信APP支付
- - -广而告之
- - - - - - -极速开发微信公众号。为您节约更多时间,去陪恋人、家人和朋友 :)
-weixin_guide 是基于jfinal-weixin SDK开发的实战项目。
-欢迎Start支持项目发展:)
-https://gitee.com/javen205/weixin_guide
-').html(content);
-
- $link.appendTo($title);
- $title.appendTo($li);
- $content.appendTo($li);
- $li.appendTo($searchList);
- });
- }
-
- function launchSearch(q) {
- // Add class for loading
- $body.addClass('with-search');
- $body.addClass('search-loading');
-
- // Launch search query
- throttle(gitbook.search.query(q, 0, MAX_RESULTS)
- .then(function(results) {
- displayResults(results);
- })
- .always(function() {
- $body.removeClass('search-loading');
- }), 1000);
- }
-
- function closeSearch() {
- $body.removeClass('with-search');
- $bookSearchResults.removeClass('open');
- }
-
- function launchSearchFromQueryString() {
- var q = getParameterByName('q');
- if (q && q.length > 0) {
- // Update search input
- $searchInput.val(q);
-
- // Launch search
- launchSearch(q);
- }
- }
-
- function bindSearch() {
- // Bind DOM
- $searchInput = $('#book-search-input input');
- $bookSearchResults = $('#book-search-results');
- $searchList = $bookSearchResults.find('.search-results-list');
- $searchTitle = $bookSearchResults.find('.search-results-title');
- $searchResultsCount = $searchTitle.find('.search-results-count');
- $searchQuery = $searchTitle.find('.search-query');
-
- // Launch query based on input content
- function handleUpdate() {
- var q = $searchInput.val();
-
- if (q.length == 0) {
- closeSearch();
- }
- else {
- launchSearch(q);
- }
- }
-
- // Detect true content change in search input
- // Workaround for IE < 9
- var propertyChangeUnbound = false;
- $searchInput.on('propertychange', function(e) {
- if (e.originalEvent.propertyName == 'value') {
- handleUpdate();
- }
- });
-
- // HTML5 (IE9 & others)
- $searchInput.on('input', function(e) {
- // Unbind propertychange event for IE9+
- if (!propertyChangeUnbound) {
- $(this).unbind('propertychange');
- propertyChangeUnbound = true;
- }
-
- handleUpdate();
- });
-
- // Push to history on blur
- $searchInput.on('blur', function(e) {
- // Update history state
- if (usePushState) {
- var uri = updateQueryString('q', $(this).val());
- history.pushState({ path: uri }, null, uri);
- }
- });
- }
-
- gitbook.events.on('page.change', function() {
- bindSearch();
- closeSearch();
-
- // Launch search based on query parameter
- if (gitbook.search.isInitialized()) {
- launchSearchFromQueryString();
- }
- });
-
- gitbook.events.on('search.ready', function() {
- bindSearch();
-
- // Launch search from query param at start
- launchSearchFromQueryString();
- });
-
- function getParameterByName(name) {
- var url = window.location.href;
- name = name.replace(/[\[\]]/g, '\\$&');
- var regex = new RegExp('[?&]' + name + '(=([^]*)|&|#|$)', 'i'),
- results = regex.exec(url);
- if (!results) return null;
- if (!results[2]) return '';
- return decodeURIComponent(results[2].replace(/\+/g, ' '));
- }
-
- function updateQueryString(key, value) {
- value = encodeURIComponent(value);
-
- var url = window.location.href;
- var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'),
- hash;
-
- if (re.test(url)) {
- if (typeof value !== 'undefined' && value !== null)
- return url.replace(re, '$1' + key + '=' + value + '$2$3');
- else {
- hash = url.split('#');
- url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
- if (typeof hash[1] !== 'undefined' && hash[1] !== null)
- url += '#' + hash[1];
- return url;
- }
- }
- else {
- if (typeof value !== 'undefined' && value !== null) {
- var separator = url.indexOf('?') !== -1 ? '&' : '?';
- hash = url.split('#');
- url = hash[0] + separator + key + '=' + value;
- if (typeof hash[1] !== 'undefined' && hash[1] !== null)
- url += '#' + hash[1];
- return url;
- }
- else
- return url;
- }
- }
-});
diff --git a/docs/docs/gitbook/gitbook-plugin-sharing/buttons.js b/docs/docs/gitbook/gitbook-plugin-sharing/buttons.js
deleted file mode 100644
index 709a4e4c..00000000
--- a/docs/docs/gitbook/gitbook-plugin-sharing/buttons.js
+++ /dev/null
@@ -1,90 +0,0 @@
-require(['gitbook', 'jquery'], function(gitbook, $) {
- var SITES = {
- 'facebook': {
- 'label': 'Facebook',
- 'icon': 'fa fa-facebook',
- 'onClick': function(e) {
- e.preventDefault();
- window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href));
- }
- },
- 'twitter': {
- 'label': 'Twitter',
- 'icon': 'fa fa-twitter',
- 'onClick': function(e) {
- e.preventDefault();
- window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href));
- }
- },
- 'google': {
- 'label': 'Google+',
- 'icon': 'fa fa-google-plus',
- 'onClick': function(e) {
- e.preventDefault();
- window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href));
- }
- },
- 'weibo': {
- 'label': 'Weibo',
- 'icon': 'fa fa-weibo',
- 'onClick': function(e) {
- e.preventDefault();
- window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title));
- }
- },
- 'instapaper': {
- 'label': 'Instapaper',
- 'icon': 'fa fa-instapaper',
- 'onClick': function(e) {
- e.preventDefault();
- window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href));
- }
- },
- 'vk': {
- 'label': 'VK',
- 'icon': 'fa fa-vk',
- 'onClick': function(e) {
- e.preventDefault();
- window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href));
- }
- }
- };
-
-
-
- gitbook.events.bind('start', function(e, config) {
- var opts = config.sharing;
-
- // Create dropdown menu
- var menu = $.map(opts.all, function(id) {
- var site = SITES[id];
-
- return {
- text: site.label,
- onClick: site.onClick
- };
- });
-
- // Create main button with dropdown
- if (menu.length > 0) {
- gitbook.toolbar.createButton({
- icon: 'fa fa-share-alt',
- label: 'Share',
- position: 'right',
- dropdown: [menu]
- });
- }
-
- // Direct actions to share
- $.each(SITES, function(sideId, site) {
- if (!opts[sideId]) return;
-
- gitbook.toolbar.createButton({
- icon: site.icon,
- label: site.text,
- position: 'right',
- onClick: site.onClick
- });
- });
- });
-});
diff --git a/docs/docs/gitbook/gitbook.js b/docs/docs/gitbook/gitbook.js
deleted file mode 100644
index 13077b45..00000000
--- a/docs/docs/gitbook/gitbook.js
+++ /dev/null
@@ -1,4 +0,0 @@
-!function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s =0&&n-1)o&&o.push(i);else if(c=de.contains(i.ownerDocument,i),s=v(f.appendChild(i),"script"),c&&y(s),n)for(l=0;i=s[l++];)Ve.test(i.type||"")&&n.push(i);return f}function b(){return!0}function w(){return!1}function T(){try{return te.activeElement}catch(e){}}function C(e,t,n,r,o,i){var s,a;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(a in t)C(e,a,n,r,t[a],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(s=o,o=function(e){return de().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function j(e,t){return de.nodeName(e,"table")&&de.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e:e}function k(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function S(e,t){var n,r,o,i,s,a,u,c;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),s=Fe.set(t,i),c=i.events)){delete s.handle,s.events={};for(o in c)for(n=0,r=c[o].length;n=s&&(r!==u&&(c=void 0,l=[e]),n.rejectWith(c,l))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var s=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:a,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:a)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var s=t[2],a=t[5];o[t[1]]=s.add,a&&s.add(function(){r=a},n[3-e][2].disable,n[0][2].lock),s.add(t[3].fire),i[t[0]]=function(){return i[t[0]+"With"](this===i?void 0:this,arguments),this},i[t[0]+"With"]=s.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(c(e,i.done(s(n)).resolve,i.reject),"pending"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)c(o[n],s(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,"complete"===te.readyState||"loading"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener("DOMContentLoaded",l),e.addEventListener("load",l));var Le=function(e,t,n,r,o,i,s){var a=0,u=e.length,c=null==n;if("object"===de.type(n)){o=!0;for(a in n)Le(e,t,a,n[a],!0,i,s)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(de(e),n)})),t))for(;a1,null,!0)},removeData:function(e){return this.each(function(){Re.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),s=function(){de.dequeue(e,t)};"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===t&&n.unshift("inprogress"),delete i.stop,o.call(e,s,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks("once memory").add(function(){Fe.remove(e,[t+"queue",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length","
"],col:[2,"
"],tr:[2,"","
"],td:[3,"
"],_default:[0,"",""]};Ge.optgroup=Ge.option,Ge.tbody=Ge.tfoot=Ge.colgroup=Ge.caption=Ge.thead,Ge.th=Ge.td;var Ye=/<|?\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement("div")),n=te.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Qe=te.documentElement,Je=/^key/,Ke=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Qe,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return"undefined"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(qe)||[""],c=t.length;c--;)a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},l=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(".")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,s)!==!1||e.addEventListener&&e.addEventListener(h,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,l):p.push(l),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||"").match(qe)||[""],c=t.length;c--;)if(a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],a=a[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=i=p.length;i--;)l=p[i],!o&&g!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(p.splice(i,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));s&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[c],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,"handle events")}},dispatch:function(e){var t,n,r,o,i,s,a=de.event.fix(e),u=new Array(arguments.length),c=(Fe.get(this,"events")||{})[a.type]||[],l=de.event.special[a.type]||{};for(u[0]=a,t=1;t","