您的位置:首页 > 其它

Ping++ 支付接口对接

2017-06-10 22:25 316 查看
一、请求charge对象

package com.bra.modules.util.pingplusplus;

import com.bra.common.utils.SystemPath;

import com.pingplusplus.Pingpp;

import org.springframework.stereotype.Service;

import java.io.File;

/**

* Created by Afon on 16/4/26.

*/

@Service

public class PingPlusPlusService {

/**

* Pingpp 管理平台对应的 API Key

*/

private final static String apiKey = "";

/**

* Pingpp 管理平台对应的应用 ID

*/

private final static String appId = "";

/**

* 你生成的私钥路径

*/

private final static String privateKeyFilePath = File.separator+SystemPath.getClassPath()+"res"+ File.separator+"rsa_private_key.pem";

public static String charge(String orderNo,int amount,String subject,String body,String channel,String clientIP){

// 设置 API Key

Pingpp.apiKey = apiKey;

// 设置私钥路径,用于请求签名

Pingpp.privateKeyPath = privateKeyFilePath;

PingPlusCharge charge=new PingPlusCharge(appId);

String chargeString=charge.createCharge(orderNo,amount,subject,body,channel,clientIP);

return chargeString;

}

}

二、生成charge 对象

package com.bra.modules.util.pingplusplus;

import com.pingplusplus.exception.PingppException;

import com.pingplusplus.model.Charge;

import java.util.Calendar;

import java.util.HashMap;

import java.util.Map;

/**

* Created by Afon on 16/4/26.

*/

public class PingPlusCharge {

private String appId;

PingPlusCharge(String appId) {

this.appId = appId;

}

public String createCharge(String orderNo, int amount, String subject, String body, String channel, String clientIP) {

/**

* 或者直接设置私钥内容

Pingpp.privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +

"... 私钥内容字符串 ...\n" +

"-----END RSA PRIVATE KEY-----\n";

*/

Map<String, Object> chargeMap = new HashMap<String, Object>();

chargeMap.put("amount", amount);

chargeMap.put("currency", "cny");

chargeMap.put("subject", subject);

chargeMap.put("body", body);

chargeMap.put("order_no", orderNo);

chargeMap.put("channel", channel);

Calendar cal = Calendar.getInstance();

cal.add(Calendar.MINUTE, 15);//15分钟失效

long timestamp = cal.getTimeInMillis()/ 1000L;

chargeMap.put("time_expire", timestamp);

chargeMap.put("client_ip", clientIP); // 客户端 ip 地址(ipv4)

Map<String, String> app = new HashMap<String, String>();

app.put("id", appId);

chargeMap.put("app", app);

String chargeString = null;

try {

//发起交易请求

Charge charge = Charge.create(chargeMap);

// 传到客户端请先转成字符串 .toString(), 调该方法,会自动转成正确的 JSON 字符串

chargeString = charge.toString();

} catch (PingppException e) {

e.printStackTrace();

}

return chargeString;

}

}

三、webhook

@RequestMapping(value = "webhooks")

@ResponseBody

public void webhooks ( HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

/*System.out.println("ping++ webhooks");*/

request.setCharacterEncoding("UTF8");

//获取头部所有信息

Enumeration headerNames = request.getHeaderNames();

String signature=null;

while (headerNames.hasMoreElements()) {

String key = (String) headerNames.nextElement();

String value = request.getHeader(key);

if("x-pingplusplus-signature".equals(key)){

signature=value;

}

}

/*System.out.println("signature"+signature);*/

// 获得 http body 内容

StringBuffer eventJson=new StringBuffer();

BufferedReader reader= null;

try {

reader = request.getReader();

do{

eventJson.append(reader.readLine());

}while(reader.read()!=-1);

} catch (IOException e) {

e.printStackTrace();

}

reader.close();

JSONObject event=JSON.parseObject(eventJson.toString());

boolean verifyRS=false;

try {

PublicKey publicKey= WebhooksVerifyService.getPubKey();

/* System.out.println(publicKey);*/

verifyRS=WebhooksVerifyService.verifyData(eventJson.toString(),signature,publicKey);

} catch (Exception e) {

e.printStackTrace();

}

if(verifyRS) {

/*System.out.println("签名验证成功");*/

if ("charge.succeeded".equals(event.get("type"))) {

JSONObject data = JSON.parseObject(event.get("data").toString());

JSONObject object = JSON.parseObject(data.get("object").toString());

String orderId = (String) object.get("order_no");

/*System.out.println("orderId:"+orderId);*/

String channel = (String) object.get("channel");

String payType = null;

int amountFen = (int) object.get("amount");

Double amountYuan = amountFen * 1.0 / 100;//ping++扣款,精确到分,而数据库精确到元

Double weiXinInput = null;

Double aliPayInput = null;

Double bankCardInput = null;

if ("wx".equals(channel)) {

payType = "4";//支付类型(1:储值卡,2:现金,3:银行卡,4:微信,5:支付宝,6:优惠券,7:打白条;8:多方式付款;9:微信个人,10:支付宝(个人))

weiXinInput = amountYuan;

} else if ("alipay".equals(channel)) {

payType = "5";

aliPayInput = amountYuan;

} else if ("upacp".equals(channel) || "upacp_wap".equals(channel) || "upacp_pc".equals(channel)) {

payType = "3";

bankCardInput = amountYuan;

}

Double couponInput;

ReserveVenueCons order = reserveAppVenueConsService.get(orderId);

if (order != null) {

Double orderPrice = order.getShouldPrice();

couponInput = orderPrice - amountYuan;//订单金额-ping++扣款 等于优惠金额

Boolean bool = reserveAppVenueConsService.saveSettlement(order, payType, amountYuan,

0.0, bankCardInput, weiXinInput, aliPayInput, couponInput);

if (bool) {

/* System.out.println("订单结算成功");*/

response.setStatus(200);

//return "订单结算成功";

} else {

/* System.out.println("订单结算失败");*/

//return "订单结算失败";

response.setStatus(500);

}

} else {

/* System.out.println("该订单不存在");*/

//return "该订单不存在";

response.setStatus(500);

}

}

}else{

/*System.out.println("签名验证失败");*/

//return "签名验证失败";

response.setStatus(500);

}

}

四、WebhooksVerifyService

package com.bra.modules.util.pingplusplus;

import com.bra.common.utils.SystemPath;

import org.apache.commons.codec.binary.Base64;

import java.io.*;

import java.security.*;

import java.security.spec.X509EncodedKeySpec;

/**

* Created by sunkai on 15/5/19. webhooks 验证签名示例

*

* 该实例演示如何对 Ping++ webhooks 通知进行验证。

* 验证是为了让开发者确认该通知来自 Ping++ ,防止恶意伪造通知。用户如果有别的验证机制,可以不进行验证签名。

*

* 验证签名需要 签名、公钥、验证信息,该实例采用文件存储方式进行演示。

* 实际项目中,需要用户从异步通知的 HTTP header 中读取签名,从 HTTP body 中读取验证信息。公钥的存储方式也需要用户自行设定。

*

* 该实例仅供演示如何验证签名,请务必不要直接 copy 到实际项目中使用。

*

*/

public class WebhooksVerifyService {

private static String pubKeyPath = File.separator+ SystemPath.getClassPath()+"res"+ File.separator+"pingpp_public_key.pem";

private static String eventPath = File.separator+SystemPath.getClassPath()+"res"+ File.separator+"webhooks_raw_post_data.json";

private static String signPath = File.separator+SystemPath.getClassPath()+"res"+ File.separator+"signature.txt";

/**

* 验证 webhooks 签名,仅供参考

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {

runDemos();

}

public static void runDemos() throws Exception {

// 该数据请从 request 中获取原始 POST 请求数据, 以下仅作为示例

String webhooksRawPostData = getStringFromFile(eventPath);

System.out.println("------- POST 原始数据 -------");

System.out.println(webhooksRawPostData);

// 签名数据请从 request 的 header 中获取, key 为 X-Pingplusplus-Signature (请忽略大小写, 建议自己做格式化)

String signature = getStringFromFile(signPath);

System.out.println("------- 签名 -------");

System.out.println(signature);

boolean result = verifyData(webhooksRawPostData, signature, getPubKey());

System.out.println("验签结果:" + (result ? "通过" : "失败"));

}

/**

* 读取文件, 部署 web 程序的时候, 签名和验签内容需要从 request 中获得

* @param filePath

* @return

* @throws Exception

*/

public static String getStringFromFile(String filePath) throws Exception {

FileInputStream in = new FileInputStream(filePath);

InputStreamReader inReader = new InputStreamReader(in, "UTF-8");

BufferedReader bf = new BufferedReader(inReader);

StringBuilder sb = new StringBuilder();

String line;

do {

line = bf.readLine();

if (line != null) {

if (sb.length() != 0) {

sb.append("\n");

}

sb.append(line);

}

} while (line != null);

return sb.toString();

}

/**

* 获得公钥

* @return

* @throws Exception

*/

public static PublicKey getPubKey() throws Exception {

String pubKeyString = getStringFromFile(pubKeyPath);

pubKeyString = pubKeyString.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");

byte[] keyBytes = Base64.decodeBase64(pubKeyString);

// generate public key

X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PublicKey publicKey = keyFactory.generatePublic(spec);

return publicKey;

}

/**

* 验证签名

* @param dataString

* @param signatureString

* @param publicKey

* @return

* @throws NoSuchAlgorithmException

* @throws InvalidKeyException

* @throws SignatureException

*/

public static boolean verifyData(String dataString, String signatureString, PublicKey publicKey)

throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {

byte[] signatureBytes = Base64.decodeBase64(signatureString);

Signature signature = Signature.getInstance("SHA256withRSA");

signature.initVerify(publicKey);

signature.update(dataString.getBytes("UTF-8"));

return signature.verify(signatureBytes);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  支付