苹果支付的逻辑如下首先客户端先请求苹果支付中心,支付中心返回给客户端一堆加密的数据。

然后客户端把这段加密的数据 base64之后传给后端。

最后由后端再去请求苹果支付中心来验证这次购买是否成功。验证通过,服务器端对业务逻辑进行处理(增加应用内的金币等)。

代码实现

服务器端请求验证通过之后的数据应该类似于{

environment = Sandbox;

receipt =     {

"adam_id" = 0;

"app_item_id" = 0;

"application_version" = 201512181924;

"bundle_id" = "me.topit.awesome.t16.pk";

"download_id" = 0;

"in_app" =         (

{

"is_trial_period" = false;

"original_purchase_date" = "2016-03-29 07:55:05 Etc/GMT";

"original_purchase_date_ms" = 1459238105000;

"original_purchase_date_pst" = "2016-03-29 00:55:05 America/Los_Angeles";

"original_transaction_id" = 1000000202075562;

"product_id" = "me.topit.sixteenpk.6";

"purchase_date" = "2016-03-29 07:55:05 Etc/GMT";

"purchase_date_ms" = 1459238105000;

"purchase_date_pst" = "2016-03-29 00:55:05 America/Los_Angeles";

quantity = 1;

"transaction_id" = 1000000202075562;

}

);

"original_application_version" = "1.0";

"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";

"original_purchase_date_ms" = 1375340400000;

"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";

"receipt_creation_date" = "2016-03-29 07:55:06 Etc/GMT";

"receipt_creation_date_ms" = 1459238106000;

"receipt_creation_date_pst" = "2016-03-29 00:55:06 America/Los_Angeles";

"receipt_type" = ProductionSandbox;

"request_date" = "2016-03-29 07:55:08 Etc/GMT";

"request_date_ms" = 1459238108417;

"request_date_pst" = "2016-03-29 00:55:08 America/Los_Angeles";

"version_external_identifier" = 0;

};

status = 0;

}

首先验证status是否为0,0表示正常。然后才是其他业务逻辑的判断。String endpoint;

if(TopitConfig.getBoolean("app.debug")){

endpoint = "https://sandbox.itunes.apple.com/verifyReceipt";

}else{

endpoint = "https://buy.itunes.apple.com/verifyReceipt";

}

JSONObject jsonObject = new JSONObject();

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

BasicHeader[] basicHeaders = new BasicHeader[1];

basicHeaders[0] = new BasicHeader("Content-Type","application/json");

String res = HttpRequestUtil.post(endpoint, jsonObject.toString(), basicHeaders, true);

JSONObject resObject = new JSONObject(res);

try{

int status = Integer.parseInt(resObject.get("status").toString());

if(status == 0){

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

int ts = (int) (inApp.getLong("purchase_date_ms")/1000);

rechargeService.applePay(loginId,inApp.get("product_id").toString(),inApp.get("transaction_id").toString(),ts);

return success();

}else{

return error("充值失败");

}

}catch (Exception e){

e.printStackTrace();

return error("充值失败");

}

上面用到HTTPS POST 直接发送实体内容的方法,如下import org.apache.http.Header;

import org.apache.http.HttpResponse;

import org.apache.http.NameValuePair;

import org.apache.http.client.HttpClient;

import org.apache.http.client.config.RequestConfig;

import org.apache.http.client.entity.UrlEncodedFormEntity;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.conn.scheme.Scheme;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.util.EntityUtils;

import org.apache.http.conn.ssl.SSLSocketFactory;

import javax.net.ssl.SSLContext;

import javax.net.ssl.TrustManager;

import javax.net.ssl.X509TrustManager;

import java.security.cert.CertificateException;

import java.security.cert.X509Certificate;

import java.util.List;

/**

* Created by zhoumengkang on 19/1/16.

*/

public class HttpRequestUtil {

public static String post(String url, String data, Header[] headers, boolean ssl) {

HttpClient httpClient = getClient(ssl);

String responseText = "";

HttpResponse httpResponse = null;

try {

HttpPost httpPost = new HttpPost(url);

RequestConfig requestConfig = RequestConfig.custom().

setSocketTimeout(5000).

setConnectTimeout(5000).

build();

httpPost.setConfig(requestConfig);

httpPost.setHeaders(headers);

httpPost.setEntity(new StringEntity(data, "UTF-8"));

httpResponse = httpClient.execute(httpPost);

if (httpResponse.getStatusLine().getStatusCode() == 200) {

responseText = EntityUtils.toString(httpResponse.getEntity());

}

} catch (Exception e) {

e.printStackTrace();

}

return responseText;

}

public static HttpClient getClient(boolean isSSL) {

HttpClient httpClient = new DefaultHttpClient();

if (isSSL) {

X509TrustManager xtm = new X509TrustManager() {

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

public X509Certificate[] getAcceptedIssuers() {

return null;

}

};

try {

SSLContext ctx = SSLContext.getInstance("TLS");

ctx.init(null, new TrustManager[]{xtm}, null);

SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);

httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));

} catch (Exception e) {

throw new RuntimeException();

}

}

return httpClient;

}

}

是不是苹果测试服务器不稳定?偶尔会返回错误,但是实际我请求都是购买同一个商品{"status":21002, "exception":"java.lang.IllegalArgumentException"}

同样的请求多次操作,发现有成功有失败,不知道是什么原因。

The data in the receipt-data property was malformed or missing.

苹果支付返回html,苹果应用内支付,服务器端的实现相关推荐

  1. 美地方法官裁决:苹果不得强迫开发者使用应用内支付

    IT之家 9 月 11 日消息 据 MacRumors 报道,备受瞩目的 Epic Games 诉苹果一案今日达成判决,美国地区法官 Yvonne Gonzalez Rogers 裁定苹果的行为是反竞 ...

  2. 接入华为应用内支付,验证购买Token接口,返回“rights invalid”

    有海外开发者向我们提问:我在应用中集成了华为应用内支付SDK(测试购买订阅型商品),按照文档说明,在服务器去请求验证购买Token接口的时候返回了{"responseCode":& ...

  3. 华为内支付流程以及服务端php校验

    一.简介 华为应用内支付服务(In-App Purchases,IAP)为App提供便捷的应用内支付体验和简便的接入流程.App通过集成华为应用内支付SDK,再调用SDK接口启动IAP收银台,即可实现 ...

  4. 接入HMS Core应用内支付服务过程中一些常见问题总结

    华为HMS Core应用内支付服务(In-App Purchases,IAP)为应用提供便捷的应用内支付体验和简便的接入流程.该服务支持客户端和服务端两种开发形式,具体可以参考官方文档. 往期文章:常 ...

  5. 软文:第三方支付技术的场景应用,支付技术延伸与国际化

    才开通cnblog博客,先不谈技术,来一篇软文,谈谈最近最popular的Fintech中的核心之一,支付,只是浅谈一下国内外日新月异的场景支付的现状与发展.先简介一下,博主,master毕业,在国外 ...

  6. 购买抖币显示苹果服务器异常,抖音刷礼物为什么显示当前设备不支持苹果应用内支付?...

    因为两者不关联,所以不支持苹果应用内支付. 抖音软件的支付和苹果内部支付没有关联好,可以换个支付方式,若用户已有可用帐户余额,首次使用苹果应用内购买DOU+币后,原帐户余额将合并为DOU+币计算.展示 ...

  7. ios 自己服务器 苹果支付_iOS游戏开发二:苹果内支付的流程(In-App Purchases)

    苹果应用内支付流程 一 服务器模式流程如下: 1. 程序向服务器发送一个请求 以抓取一份包含所有商品ID的列表 2. 服务器返回包含所有商品ID标识符的列表 3. 程序将所有商品ID列表发送到App ...

  8. Java接入苹果支付 – IAP支付 – IOS应用内支付- 完整版

    本页目录 IAP介绍 IAP参考连接 接入IAP快速导航: 准备工作 认证协议(签订银行信息) 设定商品价格 productId 上线设置 注册自己的沙箱账号: 添加沙箱账号 Java编码 大致编码如 ...

  9. 苹果应用内支付(iOS IAP)的流程与常用攻击方式

    苹果应用内支付(iOS IAP)的流程与常用攻击方式 Jan 19, 2017 常见支付流程 iap(in app purchase)指苹果应用内支付, 目前主要有两种方式. 1. 客户端直接veri ...

最新文章

  1. AI目前的根本问题——缺乏 自由意志,无法分辨真正的善恶
  2. python中国大学排名爬虫写明详细步骤-python网络爬虫入门实例:中国大学排名定向爬虫...
  3. 泰勒及洛朗展开学习笔记
  4. numpy维度交换_数据分析-gt;基本操作numpy(1)
  5. 异或加密的java算法_Java使用异或运算实现简单的加密解密算法实例代码
  6. Java数组去重的方法
  7. 1020 月饼 (25 分)—PAT (Basic Level) Practice (中文)
  8. 正态分布的前世今生(上)
  9. 【BZOJ-1090】字符串折叠 区间DP + Hash
  10. [组图]手机病毒组合拳一箭双雕 手机PC均中招(转)
  11. Tableau可视化---Tableau简介
  12. 计算机房等电位连接,《计算机房屏蔽及等电位防护措施原稿2021版》
  13. 出方向链路负载均衡技术(原理部分)
  14. Excel 2010光标移动到单元格边框时,不显示小十字(亲自实践)
  15. STM32 四轴无人机设计——遥控器PPM信号
  16. 安卓判断APP是在前台还是在后台
  17. python django廖雪峰_如何用Django从零开始搭建一个网站(0)
  18. 啊哈C——学习3.7一起来找茬
  19. 绘制Excel字符画
  20. mysql中拼接字符串

热门文章

  1. imputation文献-A systematic evaluation of single-cell RNA-sequencing imputation methods
  2. PostGIS教程十一:空间索引
  3. PRN(20210421):Task-Free Continual Learning
  4. 大数据-机器学习导论-1
  5. 生活在深圳我们需要的不是叹息与感概
  6. 在MySQL中第一章选择题_北大青鸟第二学期 123章数据库选择题
  7. 易语言安卓模拟器adb模块制作查看模拟器设备adb devices
  8. web前端—前端三剑客之JS(12):字符串
  9. 西门子SMART 200 modbus rtu通讯宇电温控器例程 运行/停止的控制及指示;温度设定,上下限报警设定
  10. IPSec 密钥加密体系概述