Java支付--苹果内购

一.苹果支付

①逻辑流程图
在这里插入图片描述

二.苹果支付流程介绍

①用户购买产品下发支付请求到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 {
    @Autowired
    ApplePayService applePayService;
    @Autowired
    ApplePayUtil 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 {
    @Override
    public 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 {


        @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;
        }
    }

    @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
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值