IOS苹果内购JAVA(服务端)二次验证代码示例及步骤
1.先导入该ApplePayUtil工具类
package com.zhangsan.pay.utils;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Locale;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* @ClassName ApplePayUtil
* @Description TODO
* @Author ZhangSan_Plus
* @Date 2021/8/3 9:41
* @Version 1.0
**/
public class ApplePayUtil{
private static class TrustAnyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private static final String url_sandbox = "https://sandbox.itunes.apple.com/verifyReceipt";
private static final String url_verify = "https://buy.itunes.apple.com/verifyReceipt";
/**
* 苹果服务器验证
*
* @param receipt 账单
* @author ZhangSan_Plus
* @url 要验证的地址
* @return null 或返回结果 沙盒 https://sandbox.itunes.apple.com/verifyReceipt
*
*/
public static String buyAppVerify(String receipt, int type) {
//环境判断 线上/开发环境用不同的请求链接
String url = "";
if (type == 0) {
//沙盒测试
url = url_sandbox;
} else {
//线上测试
url = url_verify;
}
//String url = EnvUtils.isOnline() ?url_verify : url_sandbox;
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
URL console = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.setRequestMethod("POST");
conn.setRequestProperty("content-type", "text/json");
conn.setRequestProperty("Proxy-Connection", "Keep-Alive");
conn.setDoInput(true);
conn.setDoOutput(true);
BufferedOutputStream hurlBufOus = new BufferedOutputStream(conn.getOutputStream());
//拼成固定的格式传给平台
String str = String.format(Locale.CHINA, "{\"receipt-data\":\"" + receipt + "\"}");
hurlBufOus.write(str.getBytes());
hurlBufOus.flush();
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (Exception ex) {
System.out.println("苹果服务器异常");
ex.printStackTrace();
}
return null;
}
}
2.编写ApplePayController
package com.zhangsan.pay.controller;
import com.search.basics.pojo.RespBean;
import com.zhangsan.pay.pojo.ApplePayRequest;
import com.zhangsan.pay.service.ApplePayService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @ClassName ApplePayController
* @Description TODO
* @Author ZhangSan_Plus
* @Date 2021/7/29 16:30
* @Version 1.0
**/
@RestController
@RequestMapping("/api")
public class ApplePayController {
@Resource
private ApplePayService applePayService;
/**
* @Author ZhangSan_Plus
* @Description //TODO IOS内部支付
* @Date 19:26 2021/8/2
* @Param [transactionId, payload]
* @Return com.search.basics.pojo.RespBean
* <p>
* 0 正常
* 21000 App Store不能读取你提供的JSON对象
* 21002 receipt-data域的数据有问题
* 21003 receipt无法通过验证
* 21004 提供的shared secret不匹配你账号中的shared secret
* 21005 receipt服务器当前不可用
* 21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送
* 21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务
* 21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务
* </p>
**/
@PostMapping(value = "/pay/applePay")
@ResponseBody
public RespBean applePayOrder(@RequestBody ApplePayRequest applePayRequest) {
return applePayService.applePayOrder(applePayRequest);
}
}
3.编写对应的AppleServiceImpl
此处要根据具体的业务来编写对应的代码
package com.zhangsan.pay.service.impl;
import com.alibaba.fastjson.JSON;
import com.order.feign.OrderFeign;
import com.search.basics.pojo.RespBean;
import com.zhangsan.pay.pojo.ApplePay;
import com.zhangsan.pay.pojo.ApplePayReceipt;
import com.zhangsan.pay.pojo.ApplePayRequest;
import com.zhangsan.pay.service.ApplePayService;
import com.zhangsan.pay.utils.ApplePayUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @ClassName ApplePayServiceImpl
* @Description TODO
* @Author ZhangSan_Plus
* @Date 2021/8/3 10:09
* @Version 1.0
**/
@Service
public class ApplePayServiceImpl implements ApplePayService {
@Resource
private OrderFeign orderFeign;
@Override
public RespBean applePayOrder(ApplePayRequest applePayRequest) {
try {
//1.先线上测试 发送平台验证
String pay= ApplePayUtil.buyAppVerify(applePayRequest.getTransactionReceipt(), applePayRequest.getType());
// 苹果服务器没有返回验证结果
if (pay== null) {
RespBean.error("无订单信息");
} else {
// 苹果验证有返回结果
ApplePay applePay = JSON.parseObject(pay, ApplePay.class);
if ("21007".equals(applePay.getStatus())) {
//是沙盒环境,应沙盒测试,否则执行下面
//2.再沙盒测试 发送平台验证
pay= ApplePayUtil.buyAppVerify(applePayRequest.getTransactionReceipt(), applePayRequest.getType());
applePay = JSON.parseObject(pay, ApplePay.class);
}
// 前端所提供的收据是有效的 验证成功
if ("0".equals(applePay.getStatus())) {
ApplePayReceipt receipt = applePay.getReceipt();
//如果单号一致 则开始处理逻辑
if (applePayRequest.getTransactionIdentifier().equals(receipt.getTransaction_id())) {
boolean flag = orderFeign.appleOrderDeal(applePayRequest.getTransactionIdentifier(), receipt.getPurchase_date_ms(), receipt.getProduct_id(), applePayRequest.getUserId());
if (flag) {
return RespBean.ok("操作成功");
} else {
return RespBean.ok("操作失败");
}
}
} else {
return RespBean.error("receipt数据有问题");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return RespBean.ok("验证失败");
}
}
4. 配上ApplePay需要的实体类
public class ApplePay {
private ApplePayReceipt receipt;
private String status;
}
package com.zhangsan.pay.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName ApplePayReceipt
* @Description TODO
* @Author ZhangSan_Plus
* @Date 2021/8/2 19:40
* @Version 1.0
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApplePayReceipt {
/**
* 交易编号
* eg:1000000852134037
*/
private String transaction_id;
/**
* APP所有权类型
* eg:PURCHASED
*/
private String in_app_ownership_type;
/**
* 原来的交易编号
* eg:1000000852108057
*/
private String original_transaction_id;
/**
* 数量
* eg:1
*/
private String quantity;
/**
* 唯一标识符
* eg:1e10a9ec617549f986765b8546eddd0a9f349f15
*/
private String unique_identifier;
/**
* item_id
* eg:1578853844
*/
private String item_id;
/**
* 处于介绍报价期
* eg:false
*/
private String is_in_intro_offer_period;
/**
* 购买日期
* eg:2021-08-02 03:57:56 America/Los_Angeles
*/
private String purchase_date_pst;
/**
* 原始购买日期 ms
* eg:1627900203000
*/
private String original_purchase_date_ms;
/**
* 原始购买日期
* eg:2021-08-02 03:30:03 America/Los_Angeles
*/
private String original_purchase_date_pst;
/**
* 是试用期
* eg:false
*/
private String is_trial_period;
/**
* 原始购买日期
* eg:2021-08-02 10:30:03 Etc/GMT
*/
private String original_purchase_date;
/**
* 购买日期ms
*/
private String purchase_date_ms;
/**
* 产品id
* eg:2
*/
private String product_id;
private String bvrs;
/**
* 购买日期
* eg:2021-08-02 10:57:56 Etc/GMT
*/
private String purchase_date;
private String bid;
/**
* 唯一供应商标识符
* eg:A1D7647F-019C-4D15-A23C-3A48CFBFF4E3
*/
private String unique_vendor_identifier;
}
本文作者:张三Blog
本文链接:https://www.cnblogs.com/zhangsan-plus/p/16503268.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步