一、代购业务背景:
代购业务近年兴起的一种购物模式,是帮国外客户购买中国商品。主要通过外贸代购模式,把淘宝、
天猫等电商平台的全站商品通过API接入到你的网站上,瞬间就可以架设一个有数亿产品的大型网上商城,而且可以
把这些中文的商品全部自动翻译成各国语言,能让国外客户看懂,直接在网站上下单,然后网站运营方代为购买再邮
寄给客户,收取商品差价以及代购费和运费,利润可观,市场巨大。目前跨境电子商务基本上都是采取的这种模式。
代购系统支持:
1.代购流程:国外用户选择当地语言当地货币支付选择订购淘宝商品并且支付商品费用,后台根据前端用户采购商品属性进行淘宝采购下单,然后发货至中国物流仓,中国物流仓打包称重后前端用户根据收货地址选择对应的物流下单付款,后台收到付款后安排配套物流派送,前端收货。
2.代运流程:支持电商平台以外商品下单,流程和代购流程后续流程一致
3.OEM外贸工厂定制流程:系统可接受国外用户打样定制
4.自营商城模式:系统支持后台上传自营商城至前端展示
5.代购app支持上架至谷歌市场和苹果ios市场,支持微信小程序,公众号
6.支持在线支付,线下支付,多语言,多货币,优惠券系统,积分系统,会员等级,拼团,拼邮等功能。
7.支持定制
演示站展示
代购系统演示前端站网址:https://www.1buyo.com/
代购系统演示站后端站网址:https://www.1buyo.com/admin 点击获取后台账号密码
二、东南亚ipay支付相关代码
准备资料
去Ipay88官网申请MerchantCode和MerchantKey这两个参数。
MerchantCode: 商户code,用于发起支付
MerchantKey: 商户key,用户签名使用
准备三个URL:
Request URL: 签出页,发起支付请求的地址,必须是一个HTML页面地址,把相关参数通过Form表单提交给Ipay88
Response URL: 用户发起支付后会跳转到Ipay88支付页面,用户支付过后会跳转到此页面。中途如果用户放弃支付或者支付失败都会请求此接口。Ipay88会携带一些参数给我们,我们可以判断是否成功,给前端返回一些内容等
Backend URL: 支付回调地址。类似于支付宝,微信之类的
三、支付流程
form表单提交下面的参数给Ipay88,发起支付
参 数:
MerchantCode 商户代码
PaymentId 支付方式
RefNo 订单编号(我理解的,方便与订单挂钩)
Amount 支付金额(注意类似与1,912.00这种格式)
Currency 货币
ProdDesc 产品描述
UserName 用户名
UserEmail 用户邮箱
UserContact 联系方式
Remark 备注(非必传)
Lang 编码方式,UTF-8
SignatureType 加密方式SHA256
Signature 加密串
ResponseURL 支付后跳转URL
BackendURL 支付后回调URL
我们网站跳转到Ipay88站点支付页面,用户输入相关银行卡信息进入下一步
Ipay88跳转银行系统网站,输入相关信息进入下一步
Ipay88获取银行网站返回的状态,得到支付结果并进入下一步
跳转到我们设置的Response URL,后台可以获取到Ipay88的支付状态,我们根据支付信息再次query订单是否支付成功,如果支付成功则更新订单跳转成功界面,否则跳转失败页面
结束。
四、准备提交给Ipay88的参数
// Java后台准备的支付参数返回给前端
Map<String, Object> map = new HashMap<>();
map.put("MerchantCode", merchantCode); // Ipay88商户code
map.put("PaymentId", PaymentId); // Ipay88支付渠道,我写的2就是马来西亚币
map.put("RefNo", RefNo); // 相当于订单编号
map.put("Amount", Amount); // 支付金额,1.00 两位小数,1,278.99 超过三位有逗号,哦
map.put("Currency", "MYR");// 货币,我用的MYR
map.put("ProdDesc", ProdDesc); // 产品介绍
map.put("UserName", UserName); // 用户名
map.put("UserEmail", UserEmail); // 用户邮箱
map.put("UserContact", UserContact); // 用户联系方式
map.put("Remark", Remark); // 备注
map.put("Lang", Lang); // 编码UTF-8
map.put("SignatureType", SignatureType); // 加密方式SHA256
map.put("Signature", DigestUtils.signature(merchantKey, merchantCode, RefNo, Amount, Currency)); // 签名
map.put("ResponseURL", ipay88ResponseUrl); // Request URL
map.put("BackendURL", ipay88BackendUrl); // Backend URL
// 签名加密,签名比较地址:https://payment.ipay88.com.my/epayment/testing/testsignature_256.asp
private static String SHA_256 (String password) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes());
byte[] byteData = md.digest();
//convert the byte to hex format method 1
StringBuilder sb = new StringBuilder();
for (byte byteDatum : byteData) {
sb.append(Integer.toString((byteDatum & 0xff) + 0x100, 16).substring(1));
}
System.out.println("Hash : " + sb.toString());
return sb.toString();
}
// 支付签名使用
public static String signature(String merchantKey, String merchantCode, String refNo, String amount, String currency) throws NoSuchAlgorithmException {
String s = merchantKey +
merchantCode +
refNo +
String.valueOf(amount).replace(".", "").replace(",", "") +
currency;
return SHA_256(s);
}
// 验证签名使用
public static String signature(String merchantKey, String merchantCode, String PaymentId, String refNo, String amount, String currency, String status) throws NoSuchAlgorithmException {
String s = merchantKey +
merchantCode +
PaymentId +
refNo +
String.valueOf(amount).replace(".", "").replace(",", "") +
currency +
status;
return SHA_256(s);
}
五、发起支付表单,需要通过Js给表单赋值
<FORM method="post" name="ePayment"
action="https://payment.ipay88.com.my/ePayment/entry.asp">
<INPUT type="hidden" name="MerchantCode" value="M00003">
<INPUT type="hidden" name="PaymentId" value="2">
<INPUT type="hidden" name="RefNo" value="A00000001">
<INPUT type="hidden" name="Amount" value="1.00">
<INPUT type="hidden" name="Currency" value="MYR">
<INPUT type="hidden" name="ProdDesc" value="Photo Print">
<INPUT type="hidden" name="UserName" value="John Tan">
<INPUT type="hidden" name="UserEmail" value="[email protected]">
<INPUT type="hidden" name="UserContact" value="0126500100">
<INPUT type="hidden" name="Remark" value="gfdfgd">
<INPUT type="hidden" name="Lang" value="UTF-8">
<INPUT type="hidden" name="SignatureType" value="SHA256">
<INPUT type="hidden" name="Signature"
value="b81af9c4048b0f6c447129f0f5c0eec8d67cbe19eec26f2cdaba5df4f4dc5a28">
<INPUT type="hidden" name="ResponseURL"
value="http://gx.oeob.net/mobile/respons_ipay.php">
<INPUT type="hidden" name="BackendURL"
value="http://gx.oeob.net/mobile/respons_ipay.php">
<INPUT type="submit" value="Proceed with Payment" name="Submit">
</FORM>
Reponse URL处理Ipay88的支付结果
代码展示:
String RefNo = request.getParameter("RefNo");
String TransId = request.getParameter("TransId");
String Signature = request.getParameter("Signature");
String PaymentId = request.getParameter("PaymentId");
String Amount = request.getParameter("Amount");
String Currency = request.getParameter("Currency");
String Status = request.getParameter("Status");
if ("1".equals(Status)) {
// 验证签名
String s = DigestUtils.signature(merchantKey, merchantCode, PaymentId, RefNo, Amount, Currency, Status);
if (!s.equals(Signature)) {
log.error("Ipay88签名验证错误!");
}
// 查询是否支付成功
String queryUrl = String.format("https://payment.ipay88.com.my/epayment/enquiry.asp?MerchantCode=%s&RefNo=%s&Amount=%s", merchantCode, RefNo, Amount);
String queryResult = HttpUtil.get(queryUrl);
if (!"00".equals(queryResult)) {
log.error("支付reQuery查询,支付失败。{}", queryResult);
return b;
}
EntityWrapper<Order> entityWrapper = new EntityWrapper<>();
entityWrapper.eq("order_num", RefNo);
Order order = orderService.selectOne(entityWrapper);
if (ValidateUtil.isEmpty(order)) {
log.error("订单未找到:{}", RefNo);
return b;
}
// 是否已经处理
if (order.getPay_status() != 1) {
log.info("{}该订单已经支付过!", order.getOrder_num());
return b;
}
order.setPay_status(Order.PAY_STATUS_PAID);
order.setOrder_status(Order.ORDER_STATUS_WAIT_SEND);
order.setPay_type(5);
order.setOut_trade_no(TransId);
orderService.updateById(order);
}
这个URL实际是返回HTML页面的,意思是一个跳转到某个页面的controller控制器。当然我们也可以一并处理支付逻辑
Backend URL处理Ipay88的支付回调结果
处理逻辑和上面Response URL的逻辑是一致的。但是这是服务器与服务器之间调用,不存在页面跳转
如何获取演示demo,点击立即开通账号
柬埔寨代购集运系统客户案例:https://www.oneday888.com 已对接ipay88支付