2019-03-29 17:39
支付完成回调的 controller 中的 action 大致代码如下:
// 接收微信支付成功后回调的 action,如果响应延迟超过 5 秒
// 微信服务端会重发该回调,所以要注意对重发的回调去重
// 最简单方法是在支付记录中用一个字段做确认标记
public void weixinpay_callback() {
String callbackString = getRawData();
Map callbackPara = PaymentKit.xmlToMap(callbackString);
// 通过微信的回调参数 produect_id 可以得到用户 id,进而得到 Account 对象
Account account = srv.getAccountFromCallBackPara(callbackPara);
String ip = IpKit.getRealIp(getRequest());
// 生成微信回调的响应 xml,告知已确认了该笔支付
String orderXml = srv.makeOrder(account, callbackPara, ip, ClubPaymentService.notify_url);
// 发送给微信息服务端
renderText(orderXml);
}
2019-03-29 17:29
jfinal.com 中的微信扫码支付过程大致如下:
1:在 ClubService 生成一个订单号:
public class ClubService {
// 微信官方提供的二维码扫描支付的 url 调用接口
static final String qr_code_gen_url = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
/**
* 1:为了避免在生成二维码时就创建订单,需要在 product_id 中包含元信息
* yyyyMMddHHmmss-c1-accountId,其中 c1 表示 club 订阅 1 年
*/
public String genClubPaymentQrCodeString(Account account) {
String productId = genProductIdAlsoClubOrderId(account, years);
Kv signPara = Kv.create()
.set("appid", appid)
.set("mch_id", mch_id)
.set("product_id", productId)
.set("time_stamp", Long.toString(System.currentTimeMillis() / 1000))
.set("nonce_str", Long.toString(System.currentTimeMillis()));
String sign = PaymentKit.createSign(signPara, paternerKey);
return String.format(
qr_code_gen_url, sign, appid, mch_id,
productId,
signPara.getStr("time_stamp"),
signPara.getStr("nonce_str"));
}
}
注意看上面的代码 PaymentKit 创建了 sign 参数,最后用 String.format 将 qr_code_gen_url 中的参数更新成你项目中的实际参数
2:在 ClubController 中使用 ClubService.generatePaymentQrCodeString() 方法得到一个 String 参数,也即二维码数据,使用下面的代码生成二维码,让用户扫码支付:
public class ClubController extends BaseController {
@Inject
ClubPaymentService srv;
public void genClubPaymentQrCode() {
String qrCodeContent = srv.generatePaymentQrCodeString(getLoginAccount());
renderQrCode(qrCodeContent, 215, 215);
}
}
以上两步即可完成用户支付的核心流程
2019-03-29 14:26
这都能想到,这是高手 @杜福忠
应该是 ctrl + c 复制字段名的时候将换行字符一并 copy 出来了, 手动输入创建字段名是不会出现这个问题的
2019-03-28 09:44
异常核心信息:
Caused by: java.lang.NoSuchMethodError: com.jfinal.plugin.activerecord.Db.findById(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)
解决办法是:一是升级 jfinal 到最新版本, 二是将最后一个参数强制转化成 Object,或引入一个中间变量。
如果不想升级 jfinal 解决办法如下:
Db.findById("provinceinfo", "provinceinfo_id", (Object)record.getInt("provinceinfo_id"));
或者:
Object para = record.getInt("provinceinfo_id");
Db.findById("provinceinfo", "provinceinfo_id", para);
这个问题是由 JDK 8 引发的与 jfinal 无关。而 jfinal 新版本通过调整 findByIds 解决了这个问题