一.苹果支付

①逻辑流程图

二.苹果支付流程介绍

①用户购买产品下发支付请求到app端;
②app端收到请求后调用苹果服务进行支付扣款;
③苹果服务扣款成功后返回receipt_data加密数据和支付订单号order_id给app端;
④app端将返回的数据receipt_data及order_id,请求java服务的验证接口;
⑤java服务收到参数后去请求苹果服务验证用户在app端上支付的结果;
(注:receipt_data加密数据不需要在java服务解密,直接传给苹果服务)
⑥苹果服务将验证的结果及交易信息返回给java服务,java服务根据返回的结果处理自己的业务;
⑦java服务处理完自己的业务后,将结果返回给app端;
②app端再请求苹果服务检查java服务是否已经验证;
③苹果服务告知app端,java服务是否验证;
⑧app端根据苹果服务返回的验证结果通知用户订单是否结束;

三.java代码

controller

package com.insigma.mmlove.admin.controller;import com.insigma.mmlove.admin.service.ApplePayService;
import com.insigma.mmlove.admin.util.ApplePayUtil;
import com.insigma.mmlove.common.api.Result;
import com.insigma.mmlove.common.api.ResultCode;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@Api(tags = {"苹果内购"})
@RequestMapping(value = "/apple")
public class ApplePayController {@AutowiredApplePayService applePayService;@AutowiredApplePayUtil applePayUtil;/*** @param :TransactionID订单号* @param :receipt订单加密收据* @Description: Ios客户端内购支付*/@RequestMapping("/applePay")public Result doIosRequest(@RequestParam("receipt") String receipt, @RequestParam("TransactionID") String TransactionID) {String verifyResult = applePayUtil.buyAppVerify(receipt, 0);//苹果服务器没有返回验证结果if (verifyResult == null) {return Result.failed(ResultCode.APPLE_NULL);} else {return applePayService.getAppPay(verifyResult, TransactionID);}}
}

service

package com.insigma.mmlove.admin.service.impl;import com.alibaba.fastjson.JSONObject;
import com.insigma.mmlove.admin.service.ApplePayService;
import com.insigma.mmlove.common.api.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class ApplePayServiceImpl implements ApplePayService {@Overridepublic Result getAppPay(String verifyResult, String transactionID) {JSONObject jsonObject = JSONObject.parseObject(verifyResult);String status = jsonObject.getString("status");//判断是否验证成功if ("0".equals(status)) {//app端所提供的收据是有效的,验证成功String receipt = jsonObject.getString("receipt");JSONObject returnJson = JSONObject.parseObject(receipt);String in_app = returnJson.getString("in_app");JSONObject in_appJson = JSONObject.parseObject(in_app.substring(1, in_app.length() - 1));String transactionId = in_appJson.getString("transaction_id");String in_app_ownership_type = in_appJson.getString("in_app_ownership_type");//如果验证后的订单号与app端传来的订单号一致并且状态为已支付状态则处理自己的业务if (transactionID.equals(transactionId) && "PURCHASED".equals(in_app_ownership_type)) {//===================处理自己的业务 ============================}}return Result.failed("苹果内购验证失败");}
}

util

package com.insigma.mmlove.admin.util;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.net.ssl.*;
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;@Component
public class ApplePayUtil {private static class TrustAnyTrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}}private static class TrustAnyHostnameVerifier implements HostnameVerifier {@Overridepublic boolean verify(String hostname, SSLSession session) {return true;}}@Value("${applepay.verifyUrl}")private String url_apple_pay;@Value("${applepay.verifyTestUrl}")private String test_url_apple_pay;/*** 苹果服务器验证** @param receipt 账单* @return null 或返回结果* @url 要验证的地址 沙盒 https://sandbox.itunes.apple.com/verifyReceipt*/public String buyAppVerify(String receipt, int type) {//环境判断 线上/开发环境用不同的请求链接try {String url = null;if (type == 0) {url = test_url_apple_pay; //沙盒环境,测试} else {url = url_apple_pay; //线上环境}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);conn.setConnectTimeout(3000);BufferedOutputStream hurlBufOus = new BufferedOutputStream(conn.getOutputStream());//拼成固定的格式传给平台String str = String.format(Locale.CHINA, "{\"receipt-data\":\"" + receipt + "\"}");// 直接将receipt当参数发到苹果验证就行,不用拼格//String str = String.format(Locale.CHINA, receipt);hurlBufOus.write(str.getBytes());hurlBufOus.flush();InputStream is = conn.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(is));String line = null;StringBuilder sb = new StringBuilder();while ((line = reader.readLine()) != null) {sb.append(line);}return sb.toString();} catch (Exception ex) {System.out.println("苹果服务器异常");ex.printStackTrace();}return null;}
}

参考链接:

  1. https://blog.csdn.net/m0_62949970/article/details/124570436
  2. http://www.360doc.com/content/22/0726/22/10087950_1041513199.shtml
  3. https://www.jianshu.com/p/51f2cf328481

Java支付--苹果内购相关推荐

  1. java+uniapp苹果内购

    苹果内购后端代码 苹果内购官网地址 1.注册app,填写协议.税务和银行业务 注册app,需要唯一设置Bundle identifier,然后详细填写协议.税务和银行业务 2.内购商品的添加 我的Ap ...

  2. 苹果内购验证(熟称苹果支付回调)java版

    简介: 苹果支付是直接由ios客户端调起苹果支付并支付完成后,java后台提供一个支付回调接口供ios客户端进行同步回调,只需要在该接口进行进行验证苹果支付是否支付成功,跟微信支付和支付宝支付不一样, ...

  3. java(jfinal) 接入ios苹果内购(连续包月订阅),服务端将二次验证。

    大致流程: 1.ios端进行支付,然后收到苹果的一串数据(也叫收据),然后ios端将其转码为BASE64编码的字符串. 2.ios端请求服务端接口,将数据传给服务端,服务端拿到数据后,通过一系列处理后 ...

  4. 虚拟产品之苹果内购支付/支付宝支付/微信支付的区别

    1.支付宝支付: 同步通知,异步业务逻辑处理. 直接配置异步请求接口. 2.微信支付: 同步通知,异步业务逻辑处理. 直接配置异步请求接口. 3.苹果内购支付: 同步通知,同步业务逻辑处理. 需要io ...

  5. 苹果内购支付验签(php)

    苹果支付成功后走php验证支付结果 传receipt支付凭证 ( 自动订阅:所以需要增加一个参数: password: 秘钥, 就可以了, 但是官方文档说秘钥仅仅用在自动续订上面 大家叫后台加个验证, ...

  6. 苹果内购、支付宝微信app支付H5支付、退款

    /*** @author: tjr* @Date: 2021/4/20 15:11* @Description: 支付接口*/ @Slf4j @RestController @RequestMappi ...

  7. 【iOS内购支付】Uniapp拉起苹果内购支付注意事项、实现步骤以及踩过的坑(手把手教程)

    前言 Hello!又是很长时间没有写博客了,因为最近又开始从事新项目,也是第一次接触关于uniapp开发原生IOS应用的项目,在这里做一些关于我在项目中使用苹果内购支付所实现的方式以及要注意的事项,希 ...

  8. postman关闭ssl验证_【第5期】springboot:苹果内购服务端验证

    ​苹果内购: 只要你在苹果系统购买APP中虚拟物品(虚拟货币,VIP充值等),必须通过内购方式进行支付,苹果和商家进行三七开 验证模式有两种: Validating Receipts With the ...

  9. Springboot 对接苹果内购代码

    Springboot 对接苹果内购代码 苹果内购和微信.支付宝支付流程有所不同,微信和支付宝都是通过各自的统一下单接口,拿到客户端所要的参数,之后返回给客户端,客户端支付完成进行回调并进行业务操作,而 ...

最新文章

  1. 倒计时7天!博客之星虚位以待,Macbook等你来拿
  2. 关于react中setState的深入理解
  3. Python 爬起数据时 'gbk' codec can't encode character '\xa0' 的问题
  4. HDU 4868 Information Extraction(2014 多校联合第一场 H)
  5. 可视化太酷辽!一文了解排序和搜索算法在前端中的应用
  6. 成为Java流大师–第6部分:使用流创建新的数据库应用程序
  7. 【APICloud系列|35】小米应用商店版本更新
  8. 奔跑吧兄弟变成机器人是哪一期_强竞技的《奔跑吧3》蜕变为“生活服务类综艺”,你还愿意看吗?...
  9. [BZOJ 2957]楼房重建(THU2013集训)(线段树维护单调栈)
  10. 解决启动WebLogic输入用户名密码问题以及密码重置
  11. 小米盒子投屏+android,使用小米盒子手机投屏电视看村晚
  12. umijs 隐藏开发工具_使用UmiJS框架开发React应用
  13. ajax怎样上传多张图片,多图片Ajax上传
  14. 数论 · 幂函数求导
  15. Entersekt欢迎Nicolas Huss加入董事会
  16. 计算机硬件系统不包括什么,硬件有哪些(计算机硬件不包括)
  17. Python高级动态绘图系统:复杂曲线的轨迹演示
  18. Activity、Service、子线程之间的消息传递轻松实现
  19. 三个数中寻找最大值的5种方法-C语言实现
  20. 阿里旅行 门票基础保障内容

热门文章

  1. keras离线官方文档
  2. SQLite 对时间的支持
  3. PermissionError: [Errno 13] Permission denied:报错解决
  4. 左(下)上三角、右上(下)三角输出、正(倒)三角,C语言
  5. 【论文笔记】Predictive control of aerial swarms in cluttered environments
  6. Sketch Nyquist plot 徒手绘制Nyquist 曲线
  7. 【已解决】数据库常见场景应用计算次日留存率
  8. 交互设计师修炼指南!教你从零开始成为优秀交互设计师
  9. vue3+vite3+vant搭建移动端简易模版
  10. grep查找的内容输出到文件