import com.pingplusplus.Pingpp; import com.pingplusplus.exception.PingppException; import com.pingplusplus.model.Charge; import com.pingxx.example.Main; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; /** * 处理订单生成 * * @author JadeLuo */ public class PaySlt extends SupPay { private final String wx_pub = "wx_pub"; /** * * @param request * @param response * @throws ServletException * @throws IOException */ @Override protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET,POST"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); PrintWriter out = response.getWriter(); // 设置私钥路径,用于请求签名 Pingpp.privateKeyPath = request.getRealPath("/") + "/WEB-INF/res/rsa_private_key.pem"; // 设置 API Key Pingpp.apiKey = " "; String reqInfo = request.getParameter("tk"), isEncode = request.getParameter("isencode"); if (TL.isEmpty(reqInfo)) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测请求信息为空,请检查key是否为tk").toString()); return; } try { if (TL.isEmpty(isEncode)) { reqInfo = SkpyFlx.decode(reqInfo); } log.debug("收到的tk值:" + reqInfo); } catch (Exception ex) { Logger.getLogger(PaySlt.class.getName()).log(Level.SEVERE, null, ex); } JSONObject jo = new JSONObject(reqInfo); Integer amt = jo.getInteger("amt"), nb = jo.getInteger("nb");//TODO 重构可改为nk String channel = jo.getString("channel"), usid = jo.getString("usid"), appId = jo.getString("appId"), subject = jo.getString("subject"),//订单概要 body = jo.getString("body"),//订单描述 openid = jo.getString("openid"),//订单描述 success_url = jo.getString("success_url"),//channel=alipay_pc_direct 支付宝 PC 网页支付 currency = jo.getString("currency");//货币 cny人民币 if (wx_pub.equals(channel)) { if (TL.isEmpty(openid)) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测支付渠道为微信公众号但客户端未指定目标公众号").toString()); return; } } if (nb == null) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测nb参数为空").toString()); return; } if (amt == null) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测amt参数为空").toString()); return; } if (TL.isEmpty(channel)) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测channel参数为空").toString()); return; } if (TL.isEmpty(usid)) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测usid为空").toString()); return; } if (TL.isEmpty(appId)) { out.println(new JSONObject().put("R", "1").put("M", "服务端检测appId参数为空").toString()); return; } String orderId = new Date().getTime() + Main.randomString(7); Charge charge = createCharge(amt, channel, CusAccessObjectUtil.getIpAddress(request), appId, orderId, currency, subject, body, openid, success_url); String sql = L.i("insert into lfsj_trans_info(nuserid,nb,orderId,samt,cdate,usid,stype,stat) values (") .a("(SELECT nuserid FROM tbuserinformation where usid=") .s(usid).a("),").a2(nb).s2(orderId).a2(amt).a2("LOCALTIMESTAMP(0)").s2(usid).s2(channel).s("C").a(")").e(); if (HSF.excute(sql)) { out.println(charge.toString()); } } /** * 接收并处理交易结果 https://www.pingxx.com/guidance/client/sdk/pc 使用 PC Web * 支付后浏览器会跳转到 extra 中相应的 URL,支付宝对应 success_url,银联对应 result_url。 * * @param amount 订单总金额,单位为对应币种的最小货币单位,例如:人民币为分(如订单总金额为 1 元,此处请填 100)。 * @param channel 支付使用的第三方支付渠道,取值范围。 alipay: 支付宝手机支付 alipay_wap:支付宝手机网页支付 * alipay_pc_direct:支付宝 PC 网页支付 alipay_qr:支付宝扫码支付 bfb:百度钱包移动快捷支付 * bfb_wap:百度钱包手机网页支付 upacp:银联全渠道支付(2015 年 1 月 1 日后的银联新商户使用。若有疑问,请与 Ping++ * 或者相关的收单行联系) upacp_wap:银联全渠道手机网页支付(2015 年 1 月 1 日后的银联新商户使用。若有疑问,请与 Ping++ * 或者相关的收单行联系) upacp_pc:银联 PC 网页支付 cp_b2b:银联企业网银支付 wx:微信支付 wx_pub:微信公众账号支付 * wx_pub_qr:微信公众账号扫码支付 yeepay_wap:易宝手机网页支付 jdpay_wap:京东手机网页支付 * cnp_u:应用内快捷支付(银联) cnp_f:应用内快捷支付(外卡) applepay_upacp:Apple Pay * fqlpay_wap:分期乐支付 qgbc_wap:量化派支付 * @param ip 发起支付请求客户端的 ip 地址,格式为 IPV4 整型,如 127.0.0.1。 * @param appId * @param orderNo 商户订单号,适配每个渠道对此参数的要求,必须在商户系统内唯一。(alipay: 1-64 位, wx: 2-32 * 位,bfb: 1-20 位,upacp: 8-40 位,yeepay_wap:1-50 位,jdpay_wap:1-30 位,cnp_u:8-20 * 位,cnp_f:8-20 位,推荐使用 8-20 位,要求数字或字母,不允许特殊字符)。 * @param currency 三位 ISO 货币代码,人民币为 cny。 * @param subject 订单概要 商品的标题,该参数最长为 32 个 Unicode * 字符,银联全渠道(upacp/upacp_wap)限制在 32 个字节。 * @param body 订单描述 商品的描述信息,该参数最长为 128 个 Unicode 字符,yeepay_wap 对于该参数长度限制为 * 100 个 Unicode 字符。 * @param openid 微信公众号 * @param success_url html5 channel=alipay_pc_direct|alipay_wap * @return */ public Charge createCharge(int amount, String channel, String ip, String appId, String orderNo, String currency, String subject, String body, String openid, String success_url) { Charge charge = null; Map<String, Object> chargeMap = new HashMap<String, Object>(); chargeMap.put("amount", amount); chargeMap.put("currency", currency); chargeMap.put("subject", subject); chargeMap.put("body", body); chargeMap.put("order_no", orderNo); chargeMap.put("channel", channel); if ("0:0:0:0:0:0:0:1".equals(ip)) {//TODO ip = "127.0.0.1"; } chargeMap.put("client_ip", ip); // 客户端 ip 地址(ipv4) Map<String, String> app = new HashMap<>(); app.put("id", appId); chargeMap.put("app", app); Map<String, Object> extra = new HashMap<>(); if ("alipay_pc_direct".equals(channel) || "alipay_wap".equals(channel)) { //https://www.pingxx.com/guidance/config extra.put("success_url", success_url); } if ("upmp_wap".equals(channel) || "upacp_pc".equals(channel)) { //https://www.pingxx.com/guidance/config extra.put("result_url", success_url); } if (TL.isNotEmpty(openid) && wx_pub.equals(channel)) { extra.put("open_id", openid);//微信公众号 } chargeMap.put("extra", extra); try { //发起交易请求 charge = Charge.create(chargeMap); // 传到客户端请先转成字符串 .toString(), 调该方法,会自动转成正确的 JSON 字符串 String chargeString = charge.toString(); log.debug("创建订单成功:\n" + chargeString); } catch (PingppException e) { log.debug("创建订单失败"); e.printStackTrace(); } return charge; } }
/** * * @param amount 订单总金额,单位为对应币种的最小货币单位,例如:人民币为分(如订单总金额为 1 元,此处请填 100)。 * @param channel 支付使用的第三方支付渠道,取值范围。 * alipay: 支付宝手机支付 alipay_wap:支付宝手机网页支付 alipay_pc_direct:支付宝 PC 网页支付 alipay_qr:支付宝扫码支付 bfb:百度钱包移动快捷支付 bfb_wap:百度钱包手机网页支付 upacp:银联全渠道支付(2015 年 1 月 1 日后的银联新商户使用。若有疑问,请与 Ping++ 或者相关的收单行联系) upacp_wap:银联全渠道手机网页支付(2015 年 1 月 1 日后的银联新商户使用。若有疑问,请与 Ping++ 或者相关的收单行联系) upacp_pc:银联 PC 网页支付 cp_b2b:银联企业网银支付 wx:微信支付 wx_pub:微信公众账号支付 wx_pub_qr:微信公众账号扫码支付 yeepay_wap:易宝手机网页支付 jdpay_wap:京东手机网页支付 cnp_u:应用内快捷支付(银联) cnp_f:应用内快捷支付(外卡) applepay_upacp:Apple Pay fqlpay_wap:分期乐支付 qgbc_wap:量化派支付 * @param ip 发起支付请求客户端的 ip 地址,格式为 IPV4 整型,如 127.0.0.1。 * @param appId * @param orderNo 商户订单号,适配每个渠道对此参数的要求,必须在商户系统内唯一。(alipay: 1-64 位, wx: 2-32 位,bfb: 1-20 位,upacp: 8-40 位,yeepay_wap:1-50 位,jdpay_wap:1-30 位,cnp_u:8-20 位,cnp_f:8-20 位,推荐使用 8-20 位,要求数字或字母,不允许特殊字符)。 * @param currency 三位 ISO 货币代码,人民币为 cny。 * @param subject 订单概要 商品的标题,该参数最长为 32 个 Unicode 字符,银联全渠道(upacp/upacp_wap)限制在 32 个字节。 * @param body 订单描述 商品的描述信息,该参数最长为 128 个 Unicode 字符,yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。 * @param openid 微信公众号 * @param success_url html5 channel=alipay_pc_direct|alipay_wap * @return */ public Charge createCharge(int amount, String channel, String ip, String appId, String orderNo, String currency, String subject, String body, String openid,String success_url) { Charge charge = null; Map<String, Object> chargeMap = new HashMap<String, Object>(); chargeMap.put("amount", amount); chargeMap.put("currency", currency); chargeMap.put("subject", subject); chargeMap.put("body", body); chargeMap.put("order_no", orderNo); chargeMap.put("channel", channel); if ("0:0:0:0:0:0:0:1".equals(ip)) {//TODO ip = "127.0.0.1"; } chargeMap.put("client_ip", ip); // 客户端 ip 地址(ipv4) Map<String, String> app = new HashMap<>(); app.put("id", appId); chargeMap.put("app", app); Map<String, Object> extra = new HashMap<>(); if ("alipay_pc_direct".equals(channel) || "alipay_wap".equals(channel)) { //https://www.pingxx.com/guidance/config extra.put("success_url",success_url); } if (TL.isNotEmpty(openid) && wx_pub.equals(channel)) { extra.put("open_id", openid);//微信公众号 } chargeMap.put("extra", extra); try { //发起交易请求 charge = Charge.create(chargeMap); // 传到客户端请先转成字符串 .toString(), 调该方法,会自动转成正确的 JSON 字符串 String chargeString = charge.toString(); log.debug("创建订单成功:\n" + chargeString); } catch (PingppException e) { e.printStackTrace(); } return charge; }