个人校验代码

@RestController

@RequestMapping("/applePay")

public class ApplePayController {

@Autowired

HDPayService hDPayService;

@Autowired

RestTemplate restTemplate;

/** 沙箱环境验证URI */

static final String URI_SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt";

/** 正式环境验证URI */

static final String URI_VERIFY = "https://buy.itunes.apple.com/verifyReceipt";

/**

* 验证

* @param order_id订单ID

* @param receiptDatareceipt-data

* @return

*/

@PostMapping("/verify")

public Result> verify(@RequestParam("order_id") Long order_id, @RequestParam("receipt-data") String receiptData) {

var verifyResult = verify(URI_VERIFY, receiptData);

verifyResult.successValidate();

JSONObject data = verifyResult.getData();

JSONObject receipt = data.getJSONObject("receipt");

JSONObject in_app = receipt.getJSONArray("in_app").getJSONObject(0);

// 获得回调参数

var pay_order = in_app.getString("transaction_id");

var apple_pay_product_id = in_app.getString("product_id");

ApplePayIPO applePayIPO = ApplePayIPO.builder()

.pay_order(pay_order)

.apple_pay_product_id(apple_pay_product_id)

.order_id(order_id)

.build();

// 支付成功

hDPayService.applePaySuccess(applePayIPO);

// 返回结果信息

return ResultInfo.success();

}

/**

* 验证

* @param uri

* @param receiptData

* @return

*/

public Result verify(String uri, String receiptData) {

JSONObject data = new JSONObject();

data.put("receipt-data", receiptData);

String rest = restTemplate.postForObject(uri, data, String.class);

JSONObject result = JSONObject.parseObject(rest);

Integer status = result.getInteger("status");

if (status == 21007) {

return verify(URI_SANDBOX, receiptData);

}

if (status != 0) {

throw new ResultException(ResultInfo.error(rest));

}

return ResultInfo.success(result);

}

}

个人业务校验代码

/**

* 苹果支付成功

* @param applePayIPO

*/

@Transactional

public void applePaySuccess(ApplePayIPO applePayIPO) {

String pay_order = applePayIPO.getPay_order();

// 1. 分布式锁-加锁

String lockKey = String.format(HD_RECHARGE_ORDER_PAY_LOCK, pay_order);

Long lockTimeout = System.currentTimeMillis() + HD_RECHARGE_ORDER_PAY_LOCK_TIMEOUT;

if (!redis.lock(lockKey, lockTimeout)) {// TODO 统一非法请求异常记录,client接口调用(IP等信息,此为骇客)

throw new AttackException(ResultErrorPrompt.ATTACK);

}

// 2. 确认支付单号

HDRechargeOrderDTO hDRechargeOrderDTO = hDRechargeOrderDAO.getHDRechargeOrder(pay_order);

if (hDRechargeOrderDTO != null) {

throw new AttackException(ResultErrorPrompt.ATTACK);

}

// 3. 获取充值订单信息

Long hd_recharge_order_id = applePayIPO.getOrder_id();

hDRechargeOrderDTO = hDRechargeOrderDAO.getHDRechargeOrder(hd_recharge_order_id);

// 4. 确认订单状态

OrderStatusEnum orderStatusEnum = hDRechargeOrderDTO.getOrder_status();

if (orderStatusEnum != OrderStatusEnum.未支付) {

throw new AttackException("【ApplePay支付回调】 - 订单状态异常,当前的订单状态是:" + orderStatusEnum.name());

}

// 5. 确认苹果支付产品ID

String apple_pay_product_id = applePayIPO.getApple_pay_product_id();

String order_apple_pay_product_id = hDRechargeOrderDTO.getApple_pay_product_id();

if (apple_pay_product_id.equals(order_apple_pay_product_id)) {

throw new AttackException("【ApplePay支付回调】 - 苹果支付产品ID异常:无效的订单金额");

}

// 6. 更新支付单号和支付金额

double pay_money_sum = hDRechargeOrderDTO.getPay_money_sum();

JSONObject update_pay_money_sum_param = new JSONObject();

update_pay_money_sum_param.put("id", hd_recharge_order_id);

update_pay_money_sum_param.put("pay_order", pay_order);

update_pay_money_sum_param.put("pay_money_sum", pay_money_sum);

update_pay_money_sum_param.put("pay_time", LocalDateTime.now());

hDRechargeOrderDAO.updateById(update_pay_money_sum_param);

// 7. 订单充值

orderRecharge(hd_recharge_order_id, PayModeEnum.苹果支付, hDRechargeOrderDTO);

// 8. 分布式锁-解锁

redis.unlock(lockKey, lockTimeout);

}

附加IPO类

@Data

@Builder

public class ApplePayIPO {

Long order_id;

String pay_order;

String apple_pay_product_id;

}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐