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; }