不想当架构师的程序猿不是好程序猿
支付相信很多人都接触过,一定也遇到过很多问题,我经历了服务端和客户端两部分的开发工作,下面我就来讲述下我接入支付的过程:
首先是银联支付,这里可以下载到需要的文档。我使用的是手机控件支付
。
C#服务端准备:
1.依赖库
2.配置文件,这是测试环境的,转生产的时候记得换生产的配置
3.开发SDK
4.证书文件
Android端准备:
1.我选择了apk插件方式调起银联支付
银联支付文档工作还是做得很好,demo以及相关的文档看了之后没多久就搞定了。这些都搞定了后,最重要的就是客户端调用服务端进行TN的获取,获取玩TN直接就能调起支付了;
以下是apk方式核心代码:
int ret = UPPayAssistEx.startPay(this, null, null, tn, mode);
if (ret == PLUGIN_NEED_UPGRADE || ret == PLUGIN_NOT_INSTALLED) {
// 需要重新安装控件
Log.e(LOG_TAG, " plugin not found or need upgrade!!!");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("完成购买需要安装银联支付控件,是否安装?");
builder.setNegativeButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
UPPayAssistEx.installUPPayPlugin(APKActivity.this);
dialog.dismiss();
}
});
builder.setPositiveButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
以下是jar方式核心代码:
UPPayAssistEx.startPayByJAR(activity, PayActivity.class, null, null,
tn, mode);
不得不说支付宝的接入方式相当容易,在它的DEMO中设置好参数,一切OK正常调起支付宝客户端支付,如果没有客户端还会自动调用H5支付页面。下面是需要的几个参数PARTNER(商户PID)、SELLER(商户收款账号)、RSA_PRIVATE(商户私钥,pkcs8格式)、RSA_PUBLIC(支付宝公钥)。
私钥的生成只要使用支付宝DEMO中的openssl目录下工具就行
生成完成后记得去支付宝中设置噢。
服务端我把客户端端需要的订单信息传输过去就OK了。
下面是关键代码
// 完整的符合支付宝参数规范的订单信息
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
+ getSignType();
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(PayDemoActivity.this);
// 调用支付接口,获取支付结果
String result = alipay.pay(payInfo);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
微信支付大家都说是个坑,确实我也被坑了很久,不过只要大家注意这几点就没问题了。如果服务端做签名的话,那这些事都让服务端去管吧,客户端只需要做好参数配对就好了。
1.需要有appid(创建应用是获得)、partnerid(商户id)、prepayid(订单生成后获得)、noncestr(随机数)、timestamp(时间戳)、package(sign=WXPay)、key(自己再微信商户平台设置的)
2.sign签名是要注意ASCII码从小到大排序,也就是签名算法提到的几点
3.包名和应用签名一定要特别注意,有DEBUG和release之分。
4.回调WXPayEntryActivity一定要在.wxapi包下
服务端统一下单代码:
StringBuilder xml = new StringBuilder();
XmlDocument xmlDoc = new XmlDocument();
try
{
String nonceStr = genNonceStr();
XmlElement root = xmlDoc.CreateElement("xml");
XmlElement appid = xmlDoc.CreateElement("appid");
appid.InnerText = WebChat_APPID;
root.AppendChild(appid);
XmlElement body = xmlDoc.CreateElement("body");//描述
body.InnerText = bodyStr;
root.AppendChild(body);
XmlElement nonce_str = xmlDoc.CreateElement("nonce_str");//描述
nonce_str.InnerText = nonceStr;
root.AppendChild(nonce_str);
XmlElement mch_id = xmlDoc.CreateElement("mch_id");//商户ID
mch_id.InnerText = WebChat_MCHID;
root.AppendChild(mch_id);
XmlElement notify_url = xmlDoc.CreateElement("notify_url");//通知URL
notify_url.InnerText = WebChat_BackURL_01;
root.AppendChild(notify_url);
XmlElement out_trade_no = xmlDoc.CreateElement("out_trade_no");//订单
out_trade_no.InnerText = orderId;
root.AppendChild(out_trade_no);
XmlElement spbill_create_ip = xmlDoc.CreateElement("spbill_create_ip");//IP
spbill_create_ip.InnerText = ip;
root.AppendChild(spbill_create_ip);
XmlElement total_fee = xmlDoc.CreateElement("total_fee");//总价
total_fee.InnerText = totalPrice;
root.AppendChild(total_fee);
XmlElement trade_type = xmlDoc.CreateElement("trade_type");//类型
trade_type.InnerText = "APP";
root.AppendChild(trade_type);
string signA = "appid=" + WebChat_APPID + "&body=" + bodyStr
+ "&mch_id=" + WebChat_MCHID + "&nonce_str=" + nonceStr + "¬ify_url=" + WebChat_BackURL_01 + "&out_trade_no=" + orderId
+ "&spbill_create_ip=" + ip + "&total_fee=" + totalPrice + "&trade_type=APP&key=" + WebChat_KEY;
XmlElement sign = xmlDoc.CreateElement("sign");
sign.InnerText = Utilities.Util.MD5(signA).ToUpper();
root.AppendChild(sign);
string Str = root.OuterXml;
return Str;
}
catch (Exception e)
{
LogWriter.WriteLog("", e);
return null;
}
客户端支付代码:
if(Wxapi==null){
Wxapi = WXAPIFactory.createWXAPI(this, AppID);
Wxapi.registerApp(AppID);
}
if(!Wxapi.isWXAppInstalled()){
SPUtil.showMsg(mContext, "您还未安装微信");
return;
}
if (prepayid == null || (prepayid).length() == 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("错误提示");
builder.setMessage("网络连接失败,请重试!");
builder.setNegativeButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
builder.create().show();
}else{
try{
String nonceStr = genNonceStr();
String timeStamp = String.valueOf(genTimeStamp());
PayReq req = new PayReq();
req.appId = AppID;
req.partnerId = partnetId;
req.prepayId = prepayid;
req.nonceStr = nonceStr;
req.timeStamp = timeStamp;
req.packageValue = "Sign=WXPay";
// 获取微信支付Sign签名
String strA="appid="+AppID +"&noncestr="+nonceStr+"&package=Sign=WXPay&partnerid="+partnetId
+"&prepayid="+prepayid+"×tamp="+timeStamp;
req.sign = MD5.getMessageDigest((strA+"&key="+Key).getBytes()).toUpperCase();
// req.extData = "app data"; // optional
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
boolean flag = Wxapi.sendReq(req);
if(!flag){
Log.e("PAY_GET", "异常:");
}
}catch(Exception e){
Log.e("PAY_GET", "异常:"+e.getMessage());
Toast.makeText(PayBaseActivity.this, "异常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
支付的介绍就到这里了。