Android三方支付:Google Play支付、MyCard支付、ONE store支付

Google Play支付:
詳情可通過VPN:https://developer.android.com/google/play/billing/billing_library_overview#java
下面記錄爲個人摘錄
1、更新應用程序的依賴關係
將以下行添加到build.gradle您應用的文件的“依賴項”部分:
dependencies {
    ...
    implementation 'com.android.billingclient:billing:2.1.0'
}
2、連接到Google Play
在發出Google Play結算請求之前,您必須先通過以下步驟建立與Google Play的連接:
調用newBuilder() 以創建的實例。 BillingClient 您還必須調用 setListener(),將傳遞給引用, PurchasesUpdatedListener 以接收有關您的應用發起的購買以及Google Play商店發起的購買的更新。
建立與Google Play的連接。設置過程是異步的,BillingClientStateListener 一旦客戶端的設置完成並且可以發出進一步的請求,您就必須實現A 來接收回調。
覆蓋 onBillingServiceDisconnected() 回調方法,並實施您自己的重試策略,以在客戶端斷開連接的情況下處理與Google Play的連接丟失。例如,BillingClient如果Google Play商店服務在後臺更新,則可能會失去其連接。 在發出進一步的請求之前,BillingClient必須調用 startConnection()方法重新啓動連接。
private BillingClient billingClient;
...
billingClient = BillingClient.newBuilder(activity).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});
注意:強烈建議您實施自己的連接重試策略並覆蓋該 onBillingServiceDisconnected() 方法。BillingClient執行任何方法時,請確保維護連接。
3、查詢應用內商品詳細信息
您在配置應用內商品時創建的唯一商品ID用於異步查詢Google Play的應用內商品詳細信息。要在Google Play中查詢應用內商品詳情,請致電 querySkuDetailsAsync()。調用此方法時,傳遞一個實例,SkuDetailsParams 該實例 指定產品ID字符串列表和一個SkuType。該SkuType可以是SkuType.INAPP一次性產品或SkuType.SUBS訂閱費。
注意:要查詢產品詳細信息,您的應用將使用您在Google Play控制檯中配置產品時定義的產品ID。有關更多信息,請參閱 添加一次性產品特定功能 或添加訂閱特定功能。
要處理異步操作的結果,還必須指定一個實現該SkuDetailsResponseListener 接口的偵聽 器。然後onSkuDetailsResponse() ,您可以重寫 以在查詢結束時通知偵聽器,如以下示例代碼所示:

List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    });
注意:premium_upgrade產品ID代表用戶可以購買一次但無限期使用的新遊戲車。可以無限期使用的一次性產品稱爲非消耗品。氣體產品ID代表氣體,用戶可以多次購買該氣體。非無限使用的一次性產品稱爲消耗品。要處理臨時資源的消耗,請參閱指示一次性產品已消耗。
您的應用應通過將其與APK捆綁在一起或從您自己的安全後端服務器中查詢來維護自己的產品ID列表。
調用 getResponseCode() 以檢索響應代碼。如果請求成功,則響應代碼爲BillingResponse.OK。有關Google Play其他可能的響應代碼的列表,請參見 BillingClient.BillingResponse。
如果發生錯誤,您可以 getDebugMessage() 用來查看相關的錯誤消息。
該谷歌Play結算庫存儲查詢結果中List的 SkuDetails 對象。然後,您可以SkuDetails 在列表中的每個對象上調用各種方法,以查看有關應用內商品的相關信息,例如其價格或說明。要查看可用的產品詳細信息,請參閱SkuDetails類中的方法列表。
以下示例顯示瞭如何使用SkuDetails上一個代碼段返回的對象來檢索應用內商品的價格:

if (result.getResponseCode() == BillingResponse.OK && skuDetailsList != null) {
   for (SkuDetails skuDetails : skuDetailsList) {
       String sku = skuDetails.getSku();
       String price = skuDetails.getPrice();
       if ("premium_upgrade".equals(sku)) {
           premiumUpgradePrice = price;
       } else if ("gas".equals(sku)) {
           gasPrice = price;
       }
   }
}

4、允許購買應用內商品
某些Android手機可能具有較舊版本的Google Play商店應用,該版本不支持某些產品類型,例如訂閱。因此,在您的應用進入計費流程之前,請致電 isFeatureSupported() 以檢查設備是否支持您要銷售的產品。有關產品類型的列表,請參見 BillingClient.FeatureType。
要從您的應用發出購買請求,請launchBillingFlow()從UI線程調用 方法。將引用傳遞給BillingFlowParams 包含相關數據的 對象以完成購買,例如商品的商品ID(skuId)和商品類型(SkuType.INAPP針對一次性商品或SkuType.SUBS訂閱商品)。要獲取的實例 BillingFlowParams ,請使用 BillingFlowParams.Builder 類:

// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build();
int responseCode = billingClient.launchBillingFlow(flowParams);

當您調用該 launchBillingFlow() 方法時,系統會顯示Google Play購買屏幕

該 launchBillingFlow() 方法返回中列出的幾個響應代碼之一 BillingClient.BillingResponse。Google Play調用將 onPurchasesUpdated() 購買操作的結果傳遞給實現該PurchasesUpdatedListener接口的偵聽 器的方法。使用setListener()前面在“ 連接到Google Play”部分中演示的方法指定了偵聽器 。
您必須實現該 onPurchasesUpdated() 方法以處理可能的響應代碼。以下代碼段顯示瞭如何覆蓋該 onPurchasesUpdated() 方法:

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponse.OK
            && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (billingResult.getResponseCode() == BillingResponse.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

成功購買會產生一個Google Play成功屏幕

成功的購買還會生成購買令牌,該令牌是代表用戶及其所購買的應用內商品的產品ID的唯一標識符。您的應用程序可以將購買令牌存儲在本地,或者理想情況下,可以將其傳遞到安全的後端服務器,該服務器可以用來驗證購買並防止欺詐。購買令牌對於每次一次性產品購買都是唯一的。但是,由於訂閱是一次性購買的,並且會在常規結算週期自動更新,因此訂閱的購買令牌在每個結算週期都保持不變。

還通過電子郵件向用戶發送包含訂單ID或交易唯一ID的交易收據。用戶會收到一封電子郵件,其中包含每次一次性產品購買以及首次訂閱購買和隨後定期自動續訂的唯一訂單ID。您可以使用訂單ID在Google Play控制檯中管理退款。有關更多詳細信息,請參閱 查看和退款您的應用程序的訂單和訂閱。

注意:代表訂購重複性的訂單號有一個附加整數,代表該訂購的特定重複性。例如,初始訂閱訂單ID可能 GPA.1234-5678-9012-34567與後續訂購ID分別爲GPA.1234-5678-9012-34567..0(第一次重複orderID), GPA.1234-5678-9012-34567..1(第二次重複orderID)等等。
注意:如果用戶在購買應用內商品時(例如在免費試用訂閱期間)沒有欠款,則訂單ID爲$ 0。例如,當用戶取消訂閱時,訂閱將保持有效,直到計費期結束。如果用戶決定重新註冊,則其帳戶中會保留一些貸方。在這種情況下,將創建一個新的購買令牌,爲$ 0創建一個訂單ID,並在信用用完後續訂。

5、確認購買(消費掉纔算真正的完結該訂單)
如果您使用的是Google Play結算庫2.0版或更高版本,則必須在三天內確認所有購買。未正確確認購買會導致這些購買被退款
Google Play支持從應用內(應用內)或應用外(應用外)購買產品。爲了使Google Play無論用戶在哪裏購買產品,都能夠確保一致的購買體驗,您必須SUCCESS在授予用戶權利後儘快確認所有通過Google Play計費庫收到狀態的購買。如果您在三天內不確認購買,則用戶會自動收到退款,Google Play會撤消購買。對於待處理的交易,購買PENDING狀態爲3天的窗口不適用。相反,它在購買移至該SUCCESS狀態時開始。
您可以使用以下方法之一確認購買:
對於易耗品,請使用 consumeAsync()客戶端API中的。
對於未消費的產品,請使用 acknowledgePurchase()客戶端API中的。
acknowledge()服務器API中也提供了一種新方法。
對於訂閱,您必須確認任何包含新購買令牌的購買。這意味着需要確認所有初始購買,計劃變更和重新註冊,但您無需確認後續續訂。要確定採購是否需要確認,您可以檢查採購中的確認字段。
該Purchase對象包括isAcknowledged() 指示是否已經確認購買的 方法。此外,服務器端API包括用於確認布爾值 Product.purchases.get()和Product.subscriptions.get()。在確認購買之前,請使用以下方法確定是否已確認購買。
此示例顯示如何確認訂閱購買:

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        // Grant entitlement to the user.
        ...

        // Acknowledge the purchase if it hasn't already been acknowledged.
        if (!purchase.isAcknowledged()) {
            AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
        }
    }
}

 

ONE store支付:

詳情可通過VPN:https://dev.onestore.co.kr/devpoc/reference/view/IAP_v17_cn

1、什麼是ONE store應用內支付(IAP)
一家商店應用內部支付(下稱IAP)是一家商店使用的,支付服務,開發者銷售手機應用程序的應用內部商品時,利用一個商店的驗證和支付系統完成向用戶支付費用,解決等價流程。一店服務(一店服務,OSS)替代開發的應用商品,OSS與一店總服務器連接執行支付工作,用於響應用戶的應用內部商品購買請求。

2、開發環境配置建議安卓應用程序程序適用的IAP SDK所需的開發環境如下:
Android 4.0及以上版本(API版本14以上)
Java SDK 1.6版本
Android studio 2.0及以上版本

3、事先準備
詳情可通過VPN:https://dev.onestore.co.kr/devpoc/reference/view/IAP_v17_04_preparation_cn
3-1、配置應用ID
3-2、填寫銀行信息
3-3、應用內商品註冊
3-3.1應用內商品個別註冊
3-3.2應用內商品批量註冊
3-4、配置認證密鑰
3-5、下載示例應用
3-6、新增應用內支付庫(Library)
3-7、設置 Android Manifest文檔
3-8、安裝ONE store應用

4、實現應用內支付
詳情可通過VPN:https://dev.onestore.co.kr/devpoc/reference/view/IAP_v17_05_implementation_cn

使用SDK實現應用內支付
4-1、發起ONE store登錄的請求
調用 launchLoginFlowAsync,請求登錄於ONE store。
以參數傳遞的requestCode用於以後確認返回至onActivityResult的數據。

/*
 * PurchaseClient的 launchLoginFlowAsync API(登錄)回調監聽器
 */
PurchaseClient.LoginFlowListener mLoginFlowListener = new PurchaseClient.LoginFlowListener() {
    @Override
    public void onSuccess() {
        Log.d(TAG, "launchLoginFlowAsync onSuccess");
        // 開發者應自行編寫登錄成功後的方案。
    }
 
    @Override
    public void onError(IapResult result) {
        Log.e(TAG, "launchLoginFlowAsync onError, " + result.toString());
    }
 
    @Override
    public void onErrorRemoteException() {
        Log.e(TAG, "launchLoginFlowAsync onError, 無法連接ONE store服務");
    }
 
    @Override
    public void onErrorSecurityException() {
        Log.e(TAG, "launchLoginFlowAsync onError, 應用狀態異常下請求支付");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "launchLoginFlowAsync onError, 需要更新ONE store客戶端 ");
    }
 
};

int IAP_API_VERSION = 5;
int LOGIN_REQUEST_CODE = 2000; // 向onActivityResult 返回的 request code
mPurchaseClient.launchLoginFlowAsync(IAP_API_VERSION, "調用Activity".this, LOGIN_REQUEST_CODE, mLoginFlowListener)

4-2、應用內支付初始化與連接

使用應用內支付SDK時,應進行初始化,創建PurchaseClient對象並執行購買方法。首先在創建PurchaseClient對象時,輸入當前Activity的Context信息和簽名密鑰值。創建對象後,執行connect連接。在此過程中,SDK中與應用內支付服務連接,啓動爲購買的各種參數設定的操作。

/*
 * PurchaseClient的 connect API 回調監聽器
 * 返回綁定成功或失敗以及是否要更新ONE store服務的結果。
 */
PurchaseClient.ServiceConnectionListener mServiceConnectionListener = new PurchaseClient.ServiceConnectionListener() {
    @Override
    public void onConnected() {
        Log.d(TAG, "Service connected");
    }
 
    @Override
    public void onDisconnected() {
        Log.d(TAG, "Service disconnected");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "connect onError, 需要更新ONE store客戶端 ");
  PurchaseClient.launchUpdateOrInstallFlow(this);
    }
};
 
 
@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
    // PurchaseClient 初始化——將公鑰作爲參數傳遞,以驗證context和Signature。
    mPurchaseClient = new PurchaseClient(this, AppSecurity.getPublicKey());
 
    // 請求綁定ONE store服務,以啓動應用內支付。
    mPurchaseClient.connect(mServiceConnectionListener);
}

請注意連接時未安裝ONE store客戶端或ONE store客戶端版本不支持應用內支付 V17版本的情況,會調用 ServiceConnectionListener之onErrorNeedUpdateException()。出現該錯誤時,調用安裝或更新ONE store客戶端的方法,即PurchaseClient.launchUpdateOrInstallFlow。

退出Activity時,在 onDestroy方法中輸入解除PurchaseClient的代碼。

@Override
protected void onDestroy() {
    super.onDestroy();
 
    if (mPurchaseClient == null) {
        Log.d(TAG, "PurchaseClient is not initialized");
        return;
    }
 
    // 關閉應用時,使用PurchaseClient中斷服務。
    mPurchaseClient.terminate();
}

4-3、查詢是否支持

開發者在正式使用應用內支付方法之前,應先調用相應方法,確認能否啓動應用內支付。
如果SDK方法是使用AIDL提供的API,以回調形式返回成功及失敗的結果。
對失敗的返回會提供使用SDK的開發者必須處理的三大錯誤(onErrorRemoteException、onErrorSecurityException、onErrorNeedUpdateException)和普通錯誤(onError)。向onError監聽器返回的IapResult有返回碼和對返回碼進行說明的Enum,開發者應根據開發方案,處理相應錯誤。

/*
 * PurchaseClient的isBillingSupportedAsync (查詢是否支持)回調監聽器
 */
PurchaseClient.BillingSupportedListener mBillingSupportedListener = new PurchaseClient.BillingSupportedListener() {
 
    @Override
    public void onSuccess() {
        Log.d(TAG, "isBillingSupportedAsync onSuccess");
    }
 
    @Override
    public void onError(IapResult result) {
        Log.e(TAG, "isBillingSupportedAsync onError, " + result.toString());
    }
 
    @Override
    public void onErrorRemoteException() {
        Log.e(TAG, "isBillingSupportedAsync onError, 無法連接ONE store服務");
    }
 
    @Override
    public void onErrorSecurityException() {
        Log.e(TAG, "isBillingSupportedAsync onError, 應用狀態異常下請求支付");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "isBillingSupportedAsync onError, 需要更新ONE store客戶端");
    }
};
// ONE store應用內支付API版本
int IAP_API_VERSION = 5;
mPurchaseClient.isBillingSupportedAsync(IAP_API_VERSION, mBillingSupportedListener);

4-4、查詢商品信息

開發者在 ArrayList輸入採用queryProductAsync方法的參數中放入想要獲取信息的應用內商品ID並調用,返回結果至已註冊的監聽器。
商品ID指開發者在開發者中心註冊商品時自定義的商品ID。商品信息會以 ProductDetail形式返回至 onSuccess監聽器。

/*
 * PurchaseClient的 queryProductsAsync API (商品信息查詢)回調監聽器
 */
PurchaseClient.QueryProductsListener mQueryProductsListener = new PurchaseClient.QueryProductsListener() {
    @Override
    public void onSuccess(List<ProductDetail> productDetails) {
        Log.d(TAG, "queryProductsAsync onSuccess, " + productDetails.toString());
    }
 
    @Override
    public void onErrorRemoteException() {
        Log.e(TAG, "queryProductsAsync onError, 無法連接ONE store服務 ");
    }
 
    @Override
    public void onErrorSecurityException() {
        Log.e(TAG, "queryProductsAsync onError, 應用狀態異常下請求支付 ");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "queryProductsAsync onError, 需要更新ONE store客戶端");
    }
 
    @Override
    public void onError(IapResult result) {
        Log.e(TAG, "queryProductsAsync onError, " + result.toString());
    }
};
 
int IAP_API_VERSION = 5;
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
ArrayList<String> productCodes = new ArrayList<>();
productCodes.add("p5000");
productCodes.add("p10000");
mPurchaseClient.queryProductsAsync(IAP_API_VERSION, productCodes, productType, mQueryProductsListener);

4-5、發起購買請求

調用launchPurchaseFlowAsync方法執行購買。調用方法時,輸入想要購買的應用內商品ID、商品名稱、商品類別和開發者任意決定的launchPurchaseFlowAsync(不超過100byte),該值用於支付成功後確認數據的正確性和附加數據,並以參數傳遞的requestCode用於確認返回至onActivityResult的數據。
購買成功時結果返回至onSuccess監聽器,以SDK的 PurchaseData規格返回。開發者基於收到的結果,再通過 developerPayload確認數據的正確性和附加數據,以簽名信息來驗證。
管理型商品,通過設置商品消耗處理爲用戶提供商品。
ONE store面向用戶開展發送優惠券、 購物返現(cashback)等各種優惠推廣活動。開發者發起購買請求時,可通過gameUserId、promotionApplicable參數,允許或控制用戶參加推廣活動。開發者選擇應用的唯一標識符及是否參與活動並傳遞給ONE store,ONE store基於該值處理用戶的活動優惠。

注意:gameUserId,protectionApplicable參數必須事先應用於ONE store經理的促銷工作。一般說來,該值不應發送。
此外,gameUserId參數應當送到散列單一值,以便在事先發送價值信息時,沒有隱私信息保護問題。

/*
* PurchaseClient的 launchPurchaseFlowAsync API (購買)回調監聽器
 */
PurchaseClient.PurchaseFlowListener mPurchaseFlowListener = new PurchaseClient.PurchaseFlowListener() {
    @Override
    public void onSuccess(PurchaseData purchaseData) {
  Log.d(TAG, "launchPurchaseFlowAsync onSuccess, " + purchaseData.toString());
        // 購買成功後檢查開發者payload。
        if (!isValidPayload(purchaseData.getDeveloperPayload())) {
            Log.d(TAG, "launchPurchaseFlowAsync onSuccess, Payload is not valid.");
            return;
        }
 
        // 購買成功後檢查簽名。
        boolean validPurchase = AppSecurity.isValidPurchase(purchaseData.getPurchaseData(), purchaseData.getSignature());
        if (validPurchase) {
            if (product5000.equals(purchaseData.getProductId())) {{
                // 管理型商品(inapp)購買成功後消耗。
                consumeItem(purchaseData);
            }
        } else {
            Log.d(TAG, "launchPurchaseFlowAsync onSuccess, Signature is not valid.");
            return;
        }
    }
 
    @Override
    public void onError(IapResult result) {
        Log.e(TAG, "launchPurchaseFlowAsync onError, " + result.toString());
    }
 
    @Override
    public void onErrorRemoteException() {
        Log.e(TAG, "launchPurchaseFlowAsync onError, 無法連接ONE store服務 ");
    }
 
    @Override
    public void onErrorSecurityException() {
        Log.e(TAG, "launchPurchaseFlowAsync onError, 應用狀態異常下請求支付 ");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "launchPurchaseFlowAsync onError, 需要更新ONE store客戶端 ");
    }
};
 
int IAP_API_VERSION = 5;
int PURCHASE_REQUEST_CODE = 1000; // 返回至onActivityResult的request code
String product5000 = "p5000"; // 請求購買的商品ID
String productName = ""; // ""時顯示開發者中心註冊的商品名稱
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
String devPayload = AppSecurity.generatePayload();
String gameUserId = ""; // 默認 ""
boolean promotionApplicable = false;
 
mPurchaseClient.launchPurchaseFlowAsync(IAP_API_VERSION, "調用Activity".this, PURCHASE_REQUEST_CODE, product5000, productName, productType, devPayload, gameUserId, promotionApplicable, mPurchaseFlowListener);

支付成功時返回至監聽器的Purchase信息參考“應用內支付參考 - getPurchaseIntent() 發起購買請求”。
支付結果會返回至調用launchPurchaseFlowAsync的Activity的onActivityResult,在這裏須添加handlePurchaseData方法,以SDK處理購買結果。啓動handlePurchaseData方法時,如果作爲請求購買的參數輸入的 PurchaseFlowListener爲null的話,會返回false(失敗)。成功或錯誤的處理結果會通過 PurchaseFlowListener來返回。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.e(TAG, "onActivityResult resultCode " + resultCode);
 
    switch (requestCode) {
        case PURCHASE_REQUEST_CODE:
            /*
             * 調用 launchPurchaseFlowAsync API 時收到的intent數據通過handlePurchaseData解析返回值。
             * 解析後返回結果通過調用 launchPurchaseFlowAsync 時的 PurchaseFlowListener 返回。
             */
            if (resultCode == Activity.RESULT_OK) {
                if (mPurchaseClient.handlePurchaseData(data) == false) {
                    Log.e(TAG, "onActivityResult handlePurchaseData false ");
                    // listener is null
                }
            } else {
                Log.e(TAG, "onActivityResult user canceled");
                // user canceled , do nothing..
            }
            break;
        default:
    }
}

4-6、商品消耗

如爲管理型商品(inapp),未消耗已購商品時無法再次購買。用戶購買商品後,其購買信息託管給ONE store,商品被消耗,ONE store立刻收回用戶購買商品的權限。也就是說,如過購買了管理型商品而未消耗,可作爲永久性商品,如購買後立刻消耗商品,可作爲消耗型商品,如超過一定期限消耗已購商品,可作爲限期型商品。要發起商品消耗請求時,將返回至launchPurchaseFlowAsync或queryPurchasesAsync的購買信息,作爲 consumeAsync 方法的參數傳遞並調用。

/*
 * PurchaseClient的 consumeAsync API (商品消耗)回調監聽器
 */
PurchaseClient.ConsumeListener mConsumeListener = new PurchaseClient.ConsumeListener() {
    @Override
    public void onSuccess(PurchaseData purchaseData) {
  Log.d(TAG, "consumeAsync onSuccess, " + purchaseData.toString());
  // 商品消耗成功後,按各開發者編寫的購買成功方案進行。
    }
 
    @Override
    public void onErrorRemoteException() {
        Log.e(TAG, "consumeAsync onError, 無法連接ONE store服務");
    }
 
    @Override
    public void onErrorSecurityException() {
        Log.e(TAG, "consumeAsync onError, 應用狀態異常下請求支付");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "consumeAsync onError, 需要更新ONE store客戶端 ");
    }
 
    @Override
    public void onError(IapResult result) {
        Log.e(TAG, "consumeAsync onError, " + result.toString());
    }
};
int IAP_API_VERSION = 5;
PurchaseData purchaseData; // 查詢購買記錄及請求購買後接到的PurchaseData
mPurchaseClient.consumeAsync(IAP_API_VERSION, purchaseData, mConsumeListener);

4-7、查詢購買記錄

調用queryPurchasesAsync方法來獲取用戶已購但未消耗的管理型商品(inapp)和用戶訂閱的包月自動支付商品(auto)。SDK會驗證簽名以確認購買信息數據僞造與否,如簽名驗證失敗,會將“IapResult”內定義的 IapResult.IAP_ERROR_SIGNATURE_VERIFICATION值返回至onError監聽器。出現錯誤表示購買信息數據有僞造的可能,有必要確認是否有abusing襲擊。
開發者查詢購買記錄獲得管理型商品(inapp),可通過設置商品消耗向用戶提供商品。

/*
 * PurchaseClient的queryPurchasesAsync API (查詢購買記錄)回調監聽器
 */
PurchaseClient.QueryPurchaseListener mQueryPurchaseListener = new PurchaseClient.QueryPurchaseListener() {
    @Override
    public void onSuccess(List<PurchaseData> purchaseDataList, String productType) {
  Log.d(TAG, "queryPurchasesAsync onSuccess, " + purchaseDataList.toString());
        if (IapEnum.ProductType.IN_APP.getType().equalsIgnoreCase(productType)) {
            // 如爲查詢購買記錄後獲取的管理型商品( inapp),先驗證簽名,成功後消耗商品。
        } else if (IapEnum.ProductType.AUTO.getType().equalsIgnoreCase(productType)) {
            // 如爲查詢購買記錄後獲取的包月自動支付商品( auto),先驗證簽名,成功後根據開發者應用處理需求編寫方案。
        }
    }
    @Override
    public void onErrorRemoteException() {
        Log.e(TAG, "queryPurchasesAsync onError, 無法連接ONE store服務");
    }
 
    @Override
    public void onErrorSecurityException() {
        Log.e(TAG, "queryPurchasesAsync onError, 應用狀態異常下請求支付");
    }
 
    @Override
    public void onErrorNeedUpdateException() {
        Log.e(TAG, "queryPurchasesAsync onError, 需要更新ONE store客戶端 ");
    }
 
    @Override
    public void onError(IapResult result) {
        Log.e(TAG, "queryPurchasesAsync onError, " + result.toString());
    }
};
int IAP_API_VERSION = 5;
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
mPurchaseClient.queryPurchasesAsync(IAP_API_VERSION, productType, mQueryPurchaseListener);

MyCard支付:

1、通過商務聯繫MyCard進行技術對接,獲得最新MyCardPaySDK.jar和接入文檔
2、導入MyCardPaySDK.jar
3、根據MyCard提供文檔設置AndroidManifest.xml
4、根據自身需求確定是走SDK支付方式還是WebView支付方式
4-1、SDK支付方式
        MyCardSDK sdk = new MyCardSDK(activity);
        //flag   true代表測試環境,false代表正式環境
        sdk.StartPayActivityForResult(flag, bean.getAuthCode());

        // 通過onActivityResult接收SDK結果
        if (requestCode == Config.Payment_RequestCode) {
            if( resultCode == -1)
            {
                JSONObject js = null;
                try {
                    js = new JSONObject(data.getStringExtra(Config.PaySDK_Result));
                    MLog.e(data.getStringExtra(Config.PaySDK_Result));
                    if (js.optInt("returnCode") == 1 && js.optInt("payResult") == 3) {
                        String orderNo = js.getString("facTradeSeq");
                        //進行你的操作
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (Exception e){
                }
            }else{
            }
        }

4-2、WEB支付方式
測試環境鏈接(http://test.mycard*)、正式環境鏈接(https://www.mycard*)不搞混亂就好,後面拼接字段需要注意

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章