org.skfiy.typhon.rnsd.service.handler.AppleRechargingHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.skfiy.typhon.rnsd.service.handler.AppleRechargingHandler.java

Source

/*
 * Copyright 2015 The Skfiy Open Association.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.skfiy.typhon.rnsd.service.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.skfiy.typhon.rnsd.domain.Platform;
import org.skfiy.typhon.rnsd.domain.Recharging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Kevin Zou <kevinz@skfiy.org>
 */
public class AppleRechargingHandler implements RechargingHandler {

    private static final Logger LOG = LoggerFactory.getLogger(AppleRechargingHandler.class);
    private static final String SANDBOX_URL = "https://sandbox.itunes.apple.com/verifyReceipt";
    private static final String VERIFY_URL = "https://buy.itunes.apple.com/verifyReceipt";

    private final HttpClientBuilder HC_BUILDER = HttpClientBuilder.create();
    private final Pattern P = Pattern.compile("(\"signature\" = \"(.*?)\";)");

    @Resource
    private Map<String, Integer> goodsPrices;

    public AppleRechargingHandler() throws Exception {
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
        HC_BUILDER.setSslcontext(sc);
    }

    @Override
    public RechargingBO handle(JSONObject json) throws TradeValidatedException {
        String uri;
        if ("Sandbox".equalsIgnoreCase(json.getString("environment"))) {
            uri = SANDBOX_URL;
        } else {
            uri = VERIFY_URL;
        }

        CloseableHttpClient hc = HC_BUILDER.build();
        HttpPost post = new HttpPost(uri);

        List<NameValuePair> nvps = new ArrayList<>();

        String receiptStr = json.getString("data");
        Matcher m = P.matcher(receiptStr);
        m.find();

        String signature = m.group(2).replaceAll(" ", "+");
        receiptStr = receiptStr.replace(m.group(2), signature);

        String receiptData = org.skfiy.typhon.rnsd.Base64.encodeBytes(receiptStr.getBytes());
        JSONObject receiptJson = new JSONObject();
        receiptJson.put("receipt-data", receiptData);

        try {

            post.setEntity(new StringEntity(receiptJson.toJSONString(), ContentType.APPLICATION_JSON));
            CloseableHttpResponse resp = hc.execute(post);

            String str = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
            JSONObject result = JSON.parseObject(str);

            if (result.getIntValue("status") != 0) {
                throw new TradeValidatedException("success", "no verify");
            }

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

            // result
            Recharging recharging = new Recharging();
            recharging.setTradeId(receipt.getString("transaction_id"));
            recharging.setPlatform(Platform.apple.getLabel());

            String callbackInfo = StringUtils.newStringUtf8(Base64.decodeBase64(json.getString("callbackInfo")));
            JSONObject extra = JSON.parseObject(callbackInfo);

            recharging.setUid(extra.getString("uid"));
            recharging.setRegion(extra.getString("region"));
            recharging.setGoods(extra.getString("goods"));

            LOG.debug("{}", extra);

            recharging.setAmount(extra.getInteger("goods"));
            recharging.setCreationTime(System.currentTimeMillis() / 1000);
            recharging.setChannel(Platform.apple.getLabel());

            return (new RechargingBO(recharging, "success"));
        } catch (Exception ex) {
            throw new TradeValidatedException("success", ex.getMessage());
        } finally {
            try {
                hc.close();
            } catch (IOException ex) {
            }
        }
    }

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

}