| @@ -0,0 +1,7 @@ | |||
| .DS_Store | |||
| .dart_tool/ | |||
| .packages | |||
| .pub/ | |||
| build/ | |||
| @@ -0,0 +1,10 @@ | |||
| # This file tracks properties of this Flutter project. | |||
| # Used by Flutter tool to assess capabilities and perform upgrades etc. | |||
| # | |||
| # This file should be version controlled and should not be manually edited. | |||
| version: | |||
| revision: c969b8af7b48bd0f4e3329ed3f112f41136d8bcd | |||
| channel: master | |||
| project_type: plugin | |||
| @@ -0,0 +1,3 @@ | |||
| ## 0.0.1 | |||
| * TODO: Describe initial release. | |||
| @@ -0,0 +1 @@ | |||
| TODO: Add your license here. | |||
| @@ -0,0 +1,8 @@ | |||
| # myketpayment | |||
| Add myket in app purchase for appeto team | |||
| ## Getting Started | |||
| add following permission to your Androidmanifest.xml | |||
| <uses-permission android:name="ir.mservices.market.BILLING" /> | |||
| @@ -0,0 +1,8 @@ | |||
| *.iml | |||
| .gradle | |||
| /local.properties | |||
| /.idea/workspace.xml | |||
| /.idea/libraries | |||
| .DS_Store | |||
| /build | |||
| /captures | |||
| @@ -0,0 +1,33 @@ | |||
| group 'ir.appeto.myketpayment' | |||
| version '1.0' | |||
| buildscript { | |||
| repositories { | |||
| google() | |||
| jcenter() | |||
| } | |||
| dependencies { | |||
| classpath 'com.android.tools.build:gradle:3.5.0' | |||
| } | |||
| } | |||
| rootProject.allprojects { | |||
| repositories { | |||
| google() | |||
| jcenter() | |||
| } | |||
| } | |||
| apply plugin: 'com.android.library' | |||
| android { | |||
| compileSdkVersion 28 | |||
| defaultConfig { | |||
| minSdkVersion 16 | |||
| } | |||
| lintOptions { | |||
| disable 'InvalidPackage' | |||
| } | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| org.gradle.jvmargs=-Xmx1536M | |||
| android.enableR8=true | |||
| android.useAndroidX=true | |||
| android.enableJetifier=true | |||
| @@ -0,0 +1,5 @@ | |||
| distributionBase=GRADLE_USER_HOME | |||
| distributionPath=wrapper/dists | |||
| zipStoreBase=GRADLE_USER_HOME | |||
| zipStorePath=wrapper/dists | |||
| distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip | |||
| @@ -0,0 +1 @@ | |||
| rootProject.name = 'myketpayment' | |||
| @@ -0,0 +1,4 @@ | |||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
| package="ir.appeto.myketpayment"> | |||
| <uses-permission android:name="ir.mservices.market.BILLING" /> | |||
| </manifest> | |||
| @@ -0,0 +1,185 @@ | |||
| /* | |||
| * Copyright (C) 2012 The Android Open Source Project | |||
| * | |||
| * 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 com.android.vending.billing; | |||
| import android.os.Bundle; | |||
| /** | |||
| * InAppBillingService is the service that provides in-app billing version 3 and beyond. | |||
| * This service provides the following features: | |||
| * 1. Provides a new API to get details of in-app items published for the app including | |||
| * price, type, title and description. | |||
| * 2. The purchase flow is synchronous and purchase information is available immediately | |||
| * after it completes. | |||
| * 3. Purchase information of in-app purchases is maintained within the Google Play system | |||
| * till the purchase is consumed. | |||
| * 4. An API to consume a purchase of an inapp item. All purchases of one-time | |||
| * in-app items are consumable and thereafter can be purchased again. | |||
| * 5. An API to get current purchases of the user immediately. This will not contain any | |||
| * consumed purchases. | |||
| * | |||
| * All calls will give a response code with the following possible values | |||
| * RESULT_OK = 0 - success | |||
| * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog | |||
| * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested | |||
| * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase | |||
| * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API | |||
| * RESULT_ERROR = 6 - Fatal error during the API action | |||
| * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned | |||
| * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned | |||
| */ | |||
| interface IInAppBillingService { | |||
| /** | |||
| * Checks support for the requested billing API version, package and in-app type. | |||
| * Minimum API version supported by this interface is 3. | |||
| * @param apiVersion the billing version which the app is using | |||
| * @param packageName the package name of the calling app | |||
| * @param type type of the in-app item being purchased "inapp" for one-time purchases | |||
| * and "subs" for subscription. | |||
| * @return RESULT_OK(0) on success, corresponding result code on failures | |||
| */ | |||
| int isBillingSupported(int apiVersion, String packageName, String type); | |||
| /** | |||
| * Provides details of a list of SKUs | |||
| * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle | |||
| * with a list JSON strings containing the productId, price, title and description. | |||
| * This API can be called with a maximum of 20 SKUs. | |||
| * @param apiVersion billing API version that the Third-party is using | |||
| * @param packageName the package name of the calling app | |||
| * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" | |||
| * @return Bundle containing the following key-value pairs | |||
| * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on | |||
| * failure as listed above. | |||
| * "DETAILS_LIST" with a StringArrayList containing purchase information | |||
| * in JSON format similar to: | |||
| * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00", | |||
| * "title : "Example Title", "description" : "This is an example description" }' | |||
| */ | |||
| Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle); | |||
| /** | |||
| * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, | |||
| * the type, a unique purchase token and an optional developer payload. | |||
| * @param apiVersion billing API version that the app is using | |||
| * @param packageName package name of the calling app | |||
| * @param sku the SKU of the in-app item as published in the developer console | |||
| * @param type the type of the in-app item ("inapp" for one-time purchases | |||
| * and "subs" for subscription). | |||
| * @param developerPayload optional argument to be sent back with the purchase information | |||
| * @return Bundle containing the following key-value pairs | |||
| * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on | |||
| * failure as listed above. | |||
| * "BUY_INTENT" - PendingIntent to start the purchase flow | |||
| * | |||
| * The Pending intent should be launched with startIntentSenderForResult. When purchase flow | |||
| * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. | |||
| * If the purchase is successful, the result data will contain the following key-value pairs | |||
| * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on | |||
| * failure as listed above. | |||
| * "INAPP_PURCHASE_DATA" - String in JSON format similar to | |||
| * '{"orderId":"12999763169054705758.1371079406387615", | |||
| * "packageName":"com.example.app", | |||
| * "productId":"exampleSku", | |||
| * "purchaseTime":1345678900000, | |||
| * "purchaseToken" : "122333444455555", | |||
| * "developerPayload":"example developer payload" }' | |||
| * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that | |||
| * was signed with the private key of the developer | |||
| * TODO: change this to app-specific keys. | |||
| */ | |||
| Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type, | |||
| String developerPayload); | |||
| /** | |||
| * Returns the current SKUs owned by the user of the type and package name specified along with | |||
| * purchase information and a signature of the data to be validated. | |||
| * This will return all SKUs that have been purchased in V3 and managed items purchased using | |||
| * V1 and V2 that have not been consumed. | |||
| * @param apiVersion billing API version that the app is using | |||
| * @param packageName package name of the calling app | |||
| * @param type the type of the in-app items being requested | |||
| * ("inapp" for one-time purchases and "subs" for subscription). | |||
| * @param continuationToken to be set as null for the first call, if the number of owned | |||
| * skus are too many, a continuationToken is returned in the response bundle. | |||
| * This method can be called again with the continuation token to get the next set of | |||
| * owned skus. | |||
| * @return Bundle containing the following key-value pairs | |||
| * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on | |||
| * failure as listed above. | |||
| * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs | |||
| * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information | |||
| * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures | |||
| * of the purchase information | |||
| * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the | |||
| * next set of in-app purchases. Only set if the | |||
| * user has more owned skus than the current list. | |||
| */ | |||
| Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken); | |||
| /** | |||
| * Consume the last purchase of the given SKU. This will result in this item being removed | |||
| * from all subsequent responses to getPurchases() and allow re-purchase of this item. | |||
| * @param apiVersion billing API version that the app is using | |||
| * @param packageName package name of the calling app | |||
| * @param purchaseToken token in the purchase information JSON that identifies the purchase | |||
| * to be consumed | |||
| * @return 0 if consumption succeeded. Appropriate error values for failures. | |||
| */ | |||
| int consumePurchase(int apiVersion, String packageName, String purchaseToken); | |||
| /** | |||
| * Returns an intent to launch the purchase flow for an in-app item by providing a SKU, | |||
| * the type, a unique purchase token and an optional developer payload. | |||
| * @param apiVersion billing API version that the app is using | |||
| * @param packageName package name of the calling app | |||
| * @param sku the SKU of the in-app item as published in the developer console | |||
| * @param type the type of the in-app item ("inapp" for one-time purchases | |||
| * and "subs" for subscription). | |||
| * @param developerPayload optional argument to be sent back with the purchase information | |||
| * @return Bundle containing the following key-value pairs | |||
| * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on | |||
| * failure as listed above. | |||
| * "BUY_INTENT" - Intent to start the purchase flow | |||
| * | |||
| * The intent should be launched with startActivityForResult. When purchase flow | |||
| * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. | |||
| * If the purchase is successful, the result data will contain the following key-value pairs | |||
| * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on | |||
| * failure as listed above. | |||
| * "INAPP_PURCHASE_DATA" - String in JSON format similar to | |||
| * '{"orderId":"12999763169054705758.1371079406387615", | |||
| * "packageName":"com.example.app", | |||
| * "productId":"exampleSku", | |||
| * "purchaseTime":1345678900000, | |||
| * "purchaseToken" : "122333444455555", | |||
| * "developerPayload":"example developer payload" }' | |||
| * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that | |||
| * was signed with the private key of the developer | |||
| * TODO: change this to app-specific keys. | |||
| */ | |||
| Bundle getBuyIntentV2(int apiVersion, String packageName, String sku, String type, | |||
| String developerPayload); | |||
| /** | |||
| * Returns the config of purchase. | |||
| * | |||
| * @return Bundle containing the following key-value pair | |||
| * "INTENT_V2_SUPPORT" with boolean value | |||
| */ | |||
| Bundle getPurchaseConfig(int apiVersion); | |||
| } | |||
| @@ -0,0 +1,315 @@ | |||
| package ir.appeto.myketpayment; | |||
| import android.app.Activity; | |||
| import android.content.Intent; | |||
| import android.util.Log; | |||
| import androidx.annotation.NonNull; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import io.flutter.embedding.engine.plugins.FlutterPlugin; | |||
| import io.flutter.embedding.engine.plugins.activity.ActivityAware; | |||
| import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; | |||
| import io.flutter.plugin.common.MethodCall; | |||
| import io.flutter.plugin.common.MethodChannel; | |||
| import io.flutter.plugin.common.MethodChannel.MethodCallHandler; | |||
| import io.flutter.plugin.common.MethodChannel.Result; | |||
| import io.flutter.plugin.common.PluginRegistry; | |||
| import io.flutter.plugin.common.PluginRegistry.Registrar; | |||
| import ir.appeto.myketpayment.util.IabHelper; | |||
| import ir.appeto.myketpayment.util.IabResult; | |||
| import ir.appeto.myketpayment.util.Inventory; | |||
| import ir.appeto.myketpayment.util.Purchase; | |||
| /** MyketpaymentPlugin */ | |||
| public class MyketpaymentPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { | |||
| /// The MethodChannel that will the communication between Flutter and native Android | |||
| /// | |||
| /// This local reference serves to register the plugin with the Flutter Engine and unregister it | |||
| /// when the Flutter Engine is detached from the Activity | |||
| private MethodChannel channel; | |||
| IabHelper mHelper; | |||
| Result _result; | |||
| static Activity _activity; | |||
| private static final String TAG = "PIA"; | |||
| static final int RC_REQUEST = 10001; | |||
| public String payload; | |||
| public String sku; | |||
| public boolean consume; | |||
| @Override | |||
| public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { | |||
| channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "myketpayment"); | |||
| channel.setMethodCallHandler(this); | |||
| } | |||
| // This static function is optional and equivalent to onAttachedToEngine. It supports the old | |||
| // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting | |||
| // plugin registration via this function while apps migrate to use the new Android APIs | |||
| // post-flutter-1.12 via https://flutter.dev/go/android-project-migration. | |||
| // | |||
| // It is encouraged to share logic between onAttachedToEngine and registerWith to keep | |||
| // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called | |||
| // depending on the user's project. onAttachedToEngine or registerWith must both be defined | |||
| // in the same class. | |||
| public static void registerWith(Registrar registrar) { | |||
| final MethodChannel channel = new MethodChannel(registrar.messenger(), "myketpayment"); | |||
| channel.setMethodCallHandler(new MyketpaymentPlugin()); | |||
| } | |||
| @Override | |||
| public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { | |||
| _result = result; | |||
| if (call.method.equals("setup")) { | |||
| setup(call, result); | |||
| } | |||
| else if (call.method.equals("buy")) { | |||
| buy(call, result); | |||
| } | |||
| else { | |||
| result.notImplemented(); | |||
| } | |||
| } | |||
| public void setup(@NonNull MethodCall call, @NonNull Result result) { | |||
| Log.d(TAG, call.argument("rsa").toString()); | |||
| // Create the helper, passing it our context and the public key to verify signatures with | |||
| String base64EncodedPublicKey = call.argument("rsa").toString(); | |||
| Log.d(TAG, "Creating IAB helper."); | |||
| mHelper = new IabHelper(_activity.getApplicationContext(), base64EncodedPublicKey); | |||
| // enable debug logging (for a production application, you should set this to false). | |||
| mHelper.enableDebugLogging(false); | |||
| // Start setup. This is asynchronous and the specified listener | |||
| // will be called once setup completes. | |||
| Log.d("PIA", "Starting setup."); | |||
| mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { | |||
| public void onIabSetupFinished(IabResult mResult) { | |||
| Log.d(TAG, "Setup finished."); | |||
| if (!mResult.isSuccess()) { | |||
| // Oh noes, there was a problem. | |||
| Log.d(TAG, "Problem setting up in-app billing: " + mResult); | |||
| _result.success(false); | |||
| return; | |||
| } | |||
| // Have we been disposed of in the meantime? If so, quit. | |||
| if (mHelper == null) { | |||
| _result.success(false); | |||
| return; | |||
| } | |||
| // IAB is fully set up. Now, let's get an inventory of stuff we own. | |||
| Log.d(TAG, "Setup successful. Querying inventory."); | |||
| mHelper.queryInventoryAsync(mGotInventoryListener); | |||
| } | |||
| }); | |||
| } | |||
| public void buy(@NonNull MethodCall call, @NonNull Result result) { | |||
| sku = call.argument("sku").toString(); | |||
| payload = call.argument("payload").toString(); | |||
| consume = call.argument("consume"); | |||
| Log.d(TAG, "consume: " + consume); | |||
| mHelper.flagEndAsync(); | |||
| mHelper.launchPurchaseFlow(_activity, sku, RC_REQUEST, | |||
| mPurchaseFinishedListener, payload); | |||
| } | |||
| // Listener that's called when we finish querying the items and subscriptions we own | |||
| IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() { | |||
| @Override | |||
| public void onQueryInventoryFinished(IabResult result, Inventory inventory) { | |||
| Log.d(TAG, "Query inventory finished."); | |||
| // Have we been disposed of in the meantime? If so, quit. | |||
| if (mHelper == null) { | |||
| _result.success(false); | |||
| return; | |||
| } | |||
| // Is it a failure? | |||
| if (result.isFailure()) { | |||
| Log.d(TAG, "Failed to query inventory: " + result); | |||
| _result.success(false); | |||
| return; | |||
| } | |||
| Log.d(TAG, "Query inventory was successful."); | |||
| _result.success(true); | |||
| } | |||
| }; | |||
| // Callback for when a purchase is finished | |||
| IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { | |||
| public void onIabPurchaseFinished(IabResult result, Purchase purchase) { | |||
| Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase); | |||
| // if we were disposed of in the meantime, quit. | |||
| if (mHelper == null) return; | |||
| if (result.isFailure()) { | |||
| Map<String, Object> response = new HashMap<String, Object>(); | |||
| response.put("purchased", false); | |||
| Log.d(TAG, "Error purchasing: " + result); | |||
| _result.success(response); | |||
| return; | |||
| } | |||
| if (!verifyDeveloperPayload(purchase)) { | |||
| Log.d(TAG, "Error purchasing. Authenticity verification failed."); | |||
| return; | |||
| } | |||
| Log.d(TAG, "Purchase successful."); | |||
| if(consume) { | |||
| mHelper.consumeAsync(purchase, mConsumeFinishedListener); | |||
| } | |||
| else { | |||
| returnResponse(purchase); | |||
| } | |||
| /*if (purchase.getSku().equals(SKU_GAS)) { | |||
| // bought 1/4 tank of gas. So consume it. | |||
| Log.d(TAG, "Purchase is gas. Starting gas consumption."); | |||
| mHelper.consumeAsync(purchase, mConsumeFinishedListener); | |||
| } | |||
| else if (purchase.getSku().equals(SKU_PREMIUM)) { | |||
| // bought the premium upgrade! | |||
| Log.d(TAG, "Purchase is premium upgrade. Congratulating user."); | |||
| } | |||
| else if (purchase.getSku().equals(SKU_INFINITE_GAS)) { | |||
| // bought the infinite gas subscription | |||
| Log.d(TAG, "Infinite gas subscription purchased."); | |||
| }*/ | |||
| } | |||
| }; | |||
| // Called when consumption is complete | |||
| IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() { | |||
| public void onConsumeFinished(Purchase purchase, IabResult result) { | |||
| Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result); | |||
| // if we were disposed of in the meantime, quit. | |||
| if (mHelper == null) return; | |||
| // We know this is the "gas" sku because it's the only one we consume, | |||
| // so we don't check which sku was consumed. If you have more than one | |||
| // sku, you probably should check... | |||
| if (result.isSuccess()) { | |||
| // successfully consumed, so we apply the effects of the item in our | |||
| // game world's logic, which in our case means filling the gas tank a bit | |||
| Log.d(TAG, "Consumption successful. Provisioning."); | |||
| } | |||
| else { | |||
| Log.d(TAG, "Error while consuming: " + result); | |||
| } | |||
| Log.d(TAG, "End consumption flow."); | |||
| returnResponse(purchase); | |||
| } | |||
| }; | |||
| void returnResponse(Purchase purchase) { | |||
| Map<String, Object> response = new HashMap<String, Object>(); | |||
| response.put("purchased", true); | |||
| response.put("orderId", purchase.getOrderId()); | |||
| response.put("packageName", purchase.getPackageName()); | |||
| response.put("sku", purchase.getSku()); | |||
| response.put("token", purchase.getToken()); | |||
| response.put("purchaseTime", purchase.getPurchaseTime()); | |||
| _result.success(response); | |||
| } | |||
| /** Verifies the developer payload of a purchase. */ | |||
| boolean verifyDeveloperPayload(Purchase p) { | |||
| String payload = p.getDeveloperPayload(); | |||
| /* | |||
| * TODO: verify that the developer payload of the purchase is correct. It will be | |||
| * the same one that you sent when initiating the purchase. | |||
| * | |||
| * WARNING: Locally generating a random string when starting a purchase and | |||
| * verifying it here might seem like a good approach, but this will fail in the | |||
| * case where the user purchases an item on one device and then uses your app on | |||
| * a different device, because on the other device you will not have access to the | |||
| * random string you originally generated. | |||
| * | |||
| * So a good developer payload has these characteristics: | |||
| * | |||
| * 1. If two different users purchase an item, the payload is different between them, | |||
| * so that one user's purchase can't be replayed to another user. | |||
| * | |||
| * 2. The payload must be such that you can verify it even when the app wasn't the | |||
| * one who initiated the purchase flow (so that items purchased by the user on | |||
| * one device work on other devices owned by the user). | |||
| * | |||
| * Using your own server to store and verify developer payloads across app | |||
| * installations is recommended. | |||
| */ | |||
| return true; | |||
| } | |||
| @Override | |||
| public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { | |||
| channel.setMethodCallHandler(null); | |||
| } | |||
| @Override | |||
| public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { | |||
| _activity = binding.getActivity(); | |||
| binding.addActivityResultListener(new PluginRegistry.ActivityResultListener() { | |||
| @Override | |||
| public boolean onActivityResult(int requestCode, int resultCode, Intent data) { | |||
| Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data); | |||
| if (mHelper == null) return false; | |||
| // Pass on the activity result to the helper for handling | |||
| if (!mHelper.handleActivityResult(requestCode, resultCode, data)) { | |||
| // not handled, so handle it ourselves (here's where you'd | |||
| // perform any handling of activity results not related to in-app | |||
| // billing... | |||
| } | |||
| else { | |||
| Log.d(TAG, "onActivityResult handled by IABUtil."); | |||
| } | |||
| return true; | |||
| } | |||
| }); | |||
| } | |||
| @Override | |||
| public void onDetachedFromActivityForConfigChanges() { | |||
| } | |||
| @Override | |||
| public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { | |||
| } | |||
| @Override | |||
| public void onDetachedFromActivity() { | |||
| } | |||
| } | |||
| @@ -0,0 +1,570 @@ | |||
| // Portions copyright 2002, Google, Inc. | |||
| // | |||
| // 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 ir.appeto.myketpayment.util; | |||
| // This code was converted from code at http://iharder.sourceforge.net/base64/ | |||
| // Lots of extraneous features were removed. | |||
| /* The original code said: | |||
| * <p> | |||
| * I am placing this code in the Public Domain. Do with it as you will. | |||
| * This software comes with no guarantees or warranties but with | |||
| * plenty of well-wishing instead! | |||
| * Please visit | |||
| * <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a> | |||
| * periodically to check for updates or to contribute improvements. | |||
| * </p> | |||
| * | |||
| * @author Robert Harder | |||
| * @author rharder@usa.net | |||
| * @version 1.3 | |||
| */ | |||
| /** | |||
| * Base64 converter class. This code is not a complete MIME encoder; | |||
| * it simply converts binary data to base64 data and back. | |||
| * | |||
| * <p>Note {@link CharBase64} is a GWT-compatible implementation of this | |||
| * class. | |||
| */ | |||
| public class Base64 { | |||
| /** Specify encoding (value is {@code true}). */ | |||
| public final static boolean ENCODE = true; | |||
| /** Specify decoding (value is {@code false}). */ | |||
| public final static boolean DECODE = false; | |||
| /** The equals sign (=) as a byte. */ | |||
| private final static byte EQUALS_SIGN = (byte) '='; | |||
| /** The new line character (\n) as a byte. */ | |||
| private final static byte NEW_LINE = (byte) '\n'; | |||
| /** | |||
| * The 64 valid Base64 values. | |||
| */ | |||
| private final static byte[] ALPHABET = | |||
| {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', | |||
| (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', | |||
| (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', | |||
| (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', | |||
| (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', | |||
| (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', | |||
| (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', | |||
| (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', | |||
| (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', | |||
| (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', | |||
| (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', | |||
| (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', | |||
| (byte) '9', (byte) '+', (byte) '/'}; | |||
| /** | |||
| * The 64 valid web safe Base64 values. | |||
| */ | |||
| private final static byte[] WEBSAFE_ALPHABET = | |||
| {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', | |||
| (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', | |||
| (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', | |||
| (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', | |||
| (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', | |||
| (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', | |||
| (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', | |||
| (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', | |||
| (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', | |||
| (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', | |||
| (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', | |||
| (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', | |||
| (byte) '9', (byte) '-', (byte) '_'}; | |||
| /** | |||
| * Translates a Base64 value to either its 6-bit reconstruction value | |||
| * or a negative number indicating some other meaning. | |||
| **/ | |||
| private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 | |||
| -5, -5, // Whitespace: Tab and Linefeed | |||
| -9, -9, // Decimal 11 - 12 | |||
| -5, // Whitespace: Carriage Return | |||
| -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 | |||
| -9, -9, -9, -9, -9, // Decimal 27 - 31 | |||
| -5, // Whitespace: Space | |||
| -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 | |||
| 62, // Plus sign at decimal 43 | |||
| -9, -9, -9, // Decimal 44 - 46 | |||
| 63, // Slash at decimal 47 | |||
| 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine | |||
| -9, -9, -9, // Decimal 58 - 60 | |||
| -1, // Equals sign at decimal 61 | |||
| -9, -9, -9, // Decimal 62 - 64 | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' | |||
| 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' | |||
| -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 | |||
| 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' | |||
| 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' | |||
| -9, -9, -9, -9, -9 // Decimal 123 - 127 | |||
| /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ | |||
| }; | |||
| /** The web safe decodabet */ | |||
| private final static byte[] WEBSAFE_DECODABET = | |||
| {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 | |||
| -5, -5, // Whitespace: Tab and Linefeed | |||
| -9, -9, // Decimal 11 - 12 | |||
| -5, // Whitespace: Carriage Return | |||
| -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 | |||
| -9, -9, -9, -9, -9, // Decimal 27 - 31 | |||
| -5, // Whitespace: Space | |||
| -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44 | |||
| 62, // Dash '-' sign at decimal 45 | |||
| -9, -9, // Decimal 46-47 | |||
| 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine | |||
| -9, -9, -9, // Decimal 58 - 60 | |||
| -1, // Equals sign at decimal 61 | |||
| -9, -9, -9, // Decimal 62 - 64 | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' | |||
| 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' | |||
| -9, -9, -9, -9, // Decimal 91-94 | |||
| 63, // Underscore '_' at decimal 95 | |||
| -9, // Decimal 96 | |||
| 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' | |||
| 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' | |||
| -9, -9, -9, -9, -9 // Decimal 123 - 127 | |||
| /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 | |||
| -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ | |||
| }; | |||
| // Indicates white space in encoding | |||
| private final static byte WHITE_SPACE_ENC = -5; | |||
| // Indicates equals sign in encoding | |||
| private final static byte EQUALS_SIGN_ENC = -1; | |||
| /** Defeats instantiation. */ | |||
| private Base64() { | |||
| } | |||
| /* ******** E N C O D I N G M E T H O D S ******** */ | |||
| /** | |||
| * Encodes up to three bytes of the array <var>source</var> | |||
| * and writes the resulting four Base64 bytes to <var>destination</var>. | |||
| * The source and destination arrays can be manipulated | |||
| * anywhere along their length by specifying | |||
| * <var>srcOffset</var> and <var>destOffset</var>. | |||
| * This method does not check to make sure your arrays | |||
| * are large enough to accommodate <var>srcOffset</var> + 3 for | |||
| * the <var>source</var> array or <var>destOffset</var> + 4 for | |||
| * the <var>destination</var> array. | |||
| * The actual number of significant bytes in your array is | |||
| * given by <var>numSigBytes</var>. | |||
| * | |||
| * @param source the array to convert | |||
| * @param srcOffset the index where conversion begins | |||
| * @param numSigBytes the number of significant bytes in your array | |||
| * @param destination the array to hold the conversion | |||
| * @param destOffset the index where output will be put | |||
| * @param alphabet is the encoding alphabet | |||
| * @return the <var>destination</var> array | |||
| * @since 1.3 | |||
| */ | |||
| private static byte[] encode3to4(byte[] source, int srcOffset, | |||
| int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) { | |||
| // 1 2 3 | |||
| // 01234567890123456789012345678901 Bit position | |||
| // --------000000001111111122222222 Array position from threeBytes | |||
| // --------| || || || | Six bit groups to index alphabet | |||
| // >>18 >>12 >> 6 >> 0 Right shift necessary | |||
| // 0x3f 0x3f 0x3f Additional AND | |||
| // Create buffer with zero-padding if there are only one or two | |||
| // significant bytes passed in the array. | |||
| // We have to shift left 24 in order to flush out the 1's that appear | |||
| // when Java treats a value as negative that is cast from a byte to an int. | |||
| int inBuff = | |||
| (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) | |||
| | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) | |||
| | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); | |||
| switch (numSigBytes) { | |||
| case 3: | |||
| destination[destOffset] = alphabet[(inBuff >>> 18)]; | |||
| destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; | |||
| destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; | |||
| destination[destOffset + 3] = alphabet[(inBuff) & 0x3f]; | |||
| return destination; | |||
| case 2: | |||
| destination[destOffset] = alphabet[(inBuff >>> 18)]; | |||
| destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; | |||
| destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; | |||
| destination[destOffset + 3] = EQUALS_SIGN; | |||
| return destination; | |||
| case 1: | |||
| destination[destOffset] = alphabet[(inBuff >>> 18)]; | |||
| destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; | |||
| destination[destOffset + 2] = EQUALS_SIGN; | |||
| destination[destOffset + 3] = EQUALS_SIGN; | |||
| return destination; | |||
| default: | |||
| return destination; | |||
| } // end switch | |||
| } // end encode3to4 | |||
| /** | |||
| * Encodes a byte array into Base64 notation. | |||
| * Equivalent to calling | |||
| * {@code encodeBytes(source, 0, source.length)} | |||
| * | |||
| * @param source The data to convert | |||
| * @since 1.4 | |||
| */ | |||
| public static String encode(byte[] source) { | |||
| return encode(source, 0, source.length, ALPHABET, true); | |||
| } | |||
| /** | |||
| * Encodes a byte array into web safe Base64 notation. | |||
| * | |||
| * @param source The data to convert | |||
| * @param doPadding is {@code true} to pad result with '=' chars | |||
| * if it does not fall on 3 byte boundaries | |||
| */ | |||
| public static String encodeWebSafe(byte[] source, boolean doPadding) { | |||
| return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding); | |||
| } | |||
| /** | |||
| * Encodes a byte array into Base64 notation. | |||
| * | |||
| * @param source the data to convert | |||
| * @param off offset in array where conversion should begin | |||
| * @param len length of data to convert | |||
| * @param alphabet the encoding alphabet | |||
| * @param doPadding is {@code true} to pad result with '=' chars | |||
| * if it does not fall on 3 byte boundaries | |||
| * @since 1.4 | |||
| */ | |||
| public static String encode(byte[] source, int off, int len, byte[] alphabet, | |||
| boolean doPadding) { | |||
| byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE); | |||
| int outLen = outBuff.length; | |||
| // If doPadding is false, set length to truncate '=' | |||
| // padding characters | |||
| while (doPadding == false && outLen > 0) { | |||
| if (outBuff[outLen - 1] != '=') { | |||
| break; | |||
| } | |||
| outLen -= 1; | |||
| } | |||
| return new String(outBuff, 0, outLen); | |||
| } | |||
| /** | |||
| * Encodes a byte array into Base64 notation. | |||
| * | |||
| * @param source the data to convert | |||
| * @param off offset in array where conversion should begin | |||
| * @param len length of data to convert | |||
| * @param alphabet is the encoding alphabet | |||
| * @param maxLineLength maximum length of one line. | |||
| * @return the BASE64-encoded byte array | |||
| */ | |||
| public static byte[] encode(byte[] source, int off, int len, byte[] alphabet, | |||
| int maxLineLength) { | |||
| int lenDiv3 = (len + 2) / 3; // ceil(len / 3) | |||
| int len43 = lenDiv3 * 4; | |||
| byte[] outBuff = new byte[len43 // Main 4:3 | |||
| + (len43 / maxLineLength)]; // New lines | |||
| int d = 0; | |||
| int e = 0; | |||
| int len2 = len - 2; | |||
| int lineLength = 0; | |||
| for (; d < len2; d += 3, e += 4) { | |||
| // The following block of code is the same as | |||
| // encode3to4( source, d + off, 3, outBuff, e, alphabet ); | |||
| // but inlined for faster encoding (~20% improvement) | |||
| int inBuff = | |||
| ((source[d + off] << 24) >>> 8) | |||
| | ((source[d + 1 + off] << 24) >>> 16) | |||
| | ((source[d + 2 + off] << 24) >>> 24); | |||
| outBuff[e] = alphabet[(inBuff >>> 18)]; | |||
| outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f]; | |||
| outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f]; | |||
| outBuff[e + 3] = alphabet[(inBuff) & 0x3f]; | |||
| lineLength += 4; | |||
| if (lineLength == maxLineLength) { | |||
| outBuff[e + 4] = NEW_LINE; | |||
| e++; | |||
| lineLength = 0; | |||
| } // end if: end of line | |||
| } // end for: each piece of array | |||
| if (d < len) { | |||
| encode3to4(source, d + off, len - d, outBuff, e, alphabet); | |||
| lineLength += 4; | |||
| if (lineLength == maxLineLength) { | |||
| // Add a last newline | |||
| outBuff[e + 4] = NEW_LINE; | |||
| e++; | |||
| } | |||
| e += 4; | |||
| } | |||
| assert (e == outBuff.length); | |||
| return outBuff; | |||
| } | |||
| /* ******** D E C O D I N G M E T H O D S ******** */ | |||
| /** | |||
| * Decodes four bytes from array <var>source</var> | |||
| * and writes the resulting bytes (up to three of them) | |||
| * to <var>destination</var>. | |||
| * The source and destination arrays can be manipulated | |||
| * anywhere along their length by specifying | |||
| * <var>srcOffset</var> and <var>destOffset</var>. | |||
| * This method does not check to make sure your arrays | |||
| * are large enough to accommodate <var>srcOffset</var> + 4 for | |||
| * the <var>source</var> array or <var>destOffset</var> + 3 for | |||
| * the <var>destination</var> array. | |||
| * This method returns the actual number of bytes that | |||
| * were converted from the Base64 encoding. | |||
| * | |||
| * | |||
| * @param source the array to convert | |||
| * @param srcOffset the index where conversion begins | |||
| * @param destination the array to hold the conversion | |||
| * @param destOffset the index where output will be put | |||
| * @param decodabet the decodabet for decoding Base64 content | |||
| * @return the number of decoded bytes converted | |||
| * @since 1.3 | |||
| */ | |||
| private static int decode4to3(byte[] source, int srcOffset, | |||
| byte[] destination, int destOffset, byte[] decodabet) { | |||
| // Example: Dk== | |||
| if (source[srcOffset + 2] == EQUALS_SIGN) { | |||
| int outBuff = | |||
| ((decodabet[source[srcOffset]] << 24) >>> 6) | |||
| | ((decodabet[source[srcOffset + 1]] << 24) >>> 12); | |||
| destination[destOffset] = (byte) (outBuff >>> 16); | |||
| return 1; | |||
| } else if (source[srcOffset + 3] == EQUALS_SIGN) { | |||
| // Example: DkL= | |||
| int outBuff = | |||
| ((decodabet[source[srcOffset]] << 24) >>> 6) | |||
| | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) | |||
| | ((decodabet[source[srcOffset + 2]] << 24) >>> 18); | |||
| destination[destOffset] = (byte) (outBuff >>> 16); | |||
| destination[destOffset + 1] = (byte) (outBuff >>> 8); | |||
| return 2; | |||
| } else { | |||
| // Example: DkLE | |||
| int outBuff = | |||
| ((decodabet[source[srcOffset]] << 24) >>> 6) | |||
| | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) | |||
| | ((decodabet[source[srcOffset + 2]] << 24) >>> 18) | |||
| | ((decodabet[source[srcOffset + 3]] << 24) >>> 24); | |||
| destination[destOffset] = (byte) (outBuff >> 16); | |||
| destination[destOffset + 1] = (byte) (outBuff >> 8); | |||
| destination[destOffset + 2] = (byte) (outBuff); | |||
| return 3; | |||
| } | |||
| } // end decodeToBytes | |||
| /** | |||
| * Decodes data from Base64 notation. | |||
| * | |||
| * @param s the string to decode (decoded in default encoding) | |||
| * @return the decoded data | |||
| * @since 1.4 | |||
| */ | |||
| public static byte[] decode(String s) throws Base64DecoderException { | |||
| byte[] bytes = s.getBytes(); | |||
| return decode(bytes, 0, bytes.length); | |||
| } | |||
| /** | |||
| * Decodes data from web safe Base64 notation. | |||
| * Web safe encoding uses '-' instead of '+', '_' instead of '/' | |||
| * | |||
| * @param s the string to decode (decoded in default encoding) | |||
| * @return the decoded data | |||
| */ | |||
| public static byte[] decodeWebSafe(String s) throws Base64DecoderException { | |||
| byte[] bytes = s.getBytes(); | |||
| return decodeWebSafe(bytes, 0, bytes.length); | |||
| } | |||
| /** | |||
| * Decodes Base64 content in byte array format and returns | |||
| * the decoded byte array. | |||
| * | |||
| * @param source The Base64 encoded data | |||
| * @return decoded data | |||
| * @since 1.3 | |||
| * @throws Base64DecoderException | |||
| */ | |||
| public static byte[] decode(byte[] source) throws Base64DecoderException { | |||
| return decode(source, 0, source.length); | |||
| } | |||
| /** | |||
| * Decodes web safe Base64 content in byte array format and returns | |||
| * the decoded data. | |||
| * Web safe encoding uses '-' instead of '+', '_' instead of '/' | |||
| * | |||
| * @param source the string to decode (decoded in default encoding) | |||
| * @return the decoded data | |||
| */ | |||
| public static byte[] decodeWebSafe(byte[] source) | |||
| throws Base64DecoderException { | |||
| return decodeWebSafe(source, 0, source.length); | |||
| } | |||
| /** | |||
| * Decodes Base64 content in byte array format and returns | |||
| * the decoded byte array. | |||
| * | |||
| * @param source the Base64 encoded data | |||
| * @param off the offset of where to begin decoding | |||
| * @param len the length of characters to decode | |||
| * @return decoded data | |||
| * @since 1.3 | |||
| * @throws Base64DecoderException | |||
| */ | |||
| public static byte[] decode(byte[] source, int off, int len) | |||
| throws Base64DecoderException { | |||
| return decode(source, off, len, DECODABET); | |||
| } | |||
| /** | |||
| * Decodes web safe Base64 content in byte array format and returns | |||
| * the decoded byte array. | |||
| * Web safe encoding uses '-' instead of '+', '_' instead of '/' | |||
| * | |||
| * @param source the Base64 encoded data | |||
| * @param off the offset of where to begin decoding | |||
| * @param len the length of characters to decode | |||
| * @return decoded data | |||
| */ | |||
| public static byte[] decodeWebSafe(byte[] source, int off, int len) | |||
| throws Base64DecoderException { | |||
| return decode(source, off, len, WEBSAFE_DECODABET); | |||
| } | |||
| /** | |||
| * Decodes Base64 content using the supplied decodabet and returns | |||
| * the decoded byte array. | |||
| * | |||
| * @param source the Base64 encoded data | |||
| * @param off the offset of where to begin decoding | |||
| * @param len the length of characters to decode | |||
| * @param decodabet the decodabet for decoding Base64 content | |||
| * @return decoded data | |||
| */ | |||
| public static byte[] decode(byte[] source, int off, int len, byte[] decodabet) | |||
| throws Base64DecoderException { | |||
| int len34 = len * 3 / 4; | |||
| byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output | |||
| int outBuffPosn = 0; | |||
| byte[] b4 = new byte[4]; | |||
| int b4Posn = 0; | |||
| int i = 0; | |||
| byte sbiCrop = 0; | |||
| byte sbiDecode = 0; | |||
| for (i = 0; i < len; i++) { | |||
| sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits | |||
| sbiDecode = decodabet[sbiCrop]; | |||
| if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better | |||
| if (sbiDecode >= EQUALS_SIGN_ENC) { | |||
| // An equals sign (for padding) must not occur at position 0 or 1 | |||
| // and must be the last byte[s] in the encoded value | |||
| if (sbiCrop == EQUALS_SIGN) { | |||
| int bytesLeft = len - i; | |||
| byte lastByte = (byte) (source[len - 1 + off] & 0x7f); | |||
| if (b4Posn == 0 || b4Posn == 1) { | |||
| throw new Base64DecoderException( | |||
| "invalid padding byte '=' at byte offset " + i); | |||
| } else if ((b4Posn == 3 && bytesLeft > 2) | |||
| || (b4Posn == 4 && bytesLeft > 1)) { | |||
| throw new Base64DecoderException( | |||
| "padding byte '=' falsely signals end of encoded value " | |||
| + "at offset " + i); | |||
| } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) { | |||
| throw new Base64DecoderException( | |||
| "encoded value has invalid trailing byte"); | |||
| } | |||
| break; | |||
| } | |||
| b4[b4Posn++] = sbiCrop; | |||
| if (b4Posn == 4) { | |||
| outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); | |||
| b4Posn = 0; | |||
| } | |||
| } | |||
| } else { | |||
| throw new Base64DecoderException("Bad Base64 input character at " + i | |||
| + ": " + source[i + off] + "(decimal)"); | |||
| } | |||
| } | |||
| // Because web safe encoding allows non padding base64 encodes, we | |||
| // need to pad the rest of the b4 buffer with equal signs when | |||
| // b4Posn != 0. There can be at most 2 equal signs at the end of | |||
| // four characters, so the b4 buffer must have two or three | |||
| // characters. This also catches the case where the input is | |||
| // padded with EQUALS_SIGN | |||
| if (b4Posn != 0) { | |||
| if (b4Posn == 1) { | |||
| throw new Base64DecoderException("single trailing character at offset " | |||
| + (len - 1)); | |||
| } | |||
| b4[b4Posn++] = EQUALS_SIGN; | |||
| outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); | |||
| } | |||
| byte[] out = new byte[outBuffPosn]; | |||
| System.arraycopy(outBuff, 0, out, 0, outBuffPosn); | |||
| return out; | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| // Copyright 2002, Google, Inc. | |||
| // | |||
| // 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 ir.appeto.myketpayment.util; | |||
| /** | |||
| * Exception thrown when encountering an invalid Base64 input character. | |||
| * | |||
| * @author nelson | |||
| */ | |||
| public class Base64DecoderException extends Exception { | |||
| public Base64DecoderException() { | |||
| super(); | |||
| } | |||
| public Base64DecoderException(String s) { | |||
| super(s); | |||
| } | |||
| private static final long serialVersionUID = 1L; | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| /* Copyright (c) 2012 Google Inc. | |||
| * | |||
| * 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 ir.appeto.myketpayment.util; | |||
| /** | |||
| * Exception thrown when something went wrong with in-app billing. | |||
| * An IabException has an associated IabResult (an error). | |||
| * To get the IAB result that caused this exception to be thrown, | |||
| * call {@link #getResult()}. | |||
| */ | |||
| public class IabException extends Exception { | |||
| IabResult mResult; | |||
| public IabException(IabResult r) { | |||
| this(r, null); | |||
| } | |||
| public IabException(int response, String message) { | |||
| this(new IabResult(response, message)); | |||
| } | |||
| public IabException(IabResult r, Exception cause) { | |||
| super(r.getMessage(), cause); | |||
| mResult = r; | |||
| } | |||
| public IabException(int response, String message, Exception cause) { | |||
| this(new IabResult(response, message), cause); | |||
| } | |||
| /** Returns the IAB result (error) that this exception signals. */ | |||
| public IabResult getResult() { return mResult; } | |||
| } | |||
| @@ -0,0 +1,45 @@ | |||
| /* Copyright (c) 2012 Google Inc. | |||
| * | |||
| * 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 ir.appeto.myketpayment.util; | |||
| /** | |||
| * Represents the result of an in-app billing operation. | |||
| * A result is composed of a response code (an integer) and possibly a | |||
| * message (String). You can get those by calling | |||
| * {@link #getResponse} and {@link #getMessage()}, respectively. You | |||
| * can also inquire whether a result is a success or a failure by | |||
| * calling {@link #isSuccess()} and {@link #isFailure()}. | |||
| */ | |||
| public class IabResult { | |||
| int mResponse; | |||
| String mMessage; | |||
| public IabResult(int response, String message) { | |||
| mResponse = response; | |||
| if (message == null || message.trim().length() == 0) { | |||
| mMessage = IabHelper.getResponseDesc(response); | |||
| } | |||
| else { | |||
| mMessage = message + " (response: " + IabHelper.getResponseDesc(response) + ")"; | |||
| } | |||
| } | |||
| public int getResponse() { return mResponse; } | |||
| public String getMessage() { return mMessage; } | |||
| public boolean isSuccess() { return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; } | |||
| public boolean isFailure() { return !isSuccess(); } | |||
| public String toString() { return "IabResult: " + getMessage(); } | |||
| } | |||
| @@ -0,0 +1,113 @@ | |||
| /* Copyright (c) 2012 Google Inc. | |||
| * | |||
| * 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 ir.appeto.myketpayment.util; | |||
| import java.util.ArrayList; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| /** | |||
| * Represents a block of information about in-app items. | |||
| * An Inventory is returned by such methods as {@link IabHelper#queryInventory}. | |||
| */ | |||
| public class Inventory { | |||
| Map<String, SkuDetails> mSkuMap = new HashMap<String, SkuDetails>(); | |||
| Map<String, Purchase> mPurchaseMap = new HashMap<String, Purchase>(); | |||
| Inventory() { | |||
| } | |||
| /** | |||
| * Returns the listing details for an in-app product. | |||
| */ | |||
| public SkuDetails getSkuDetails(String sku) { | |||
| return mSkuMap.get(sku); | |||
| } | |||
| /** | |||
| * Returns purchase information for a given product, or null if there is no purchase. | |||
| */ | |||
| public Purchase getPurchase(String sku) { | |||
| return mPurchaseMap.get(sku); | |||
| } | |||
| /** | |||
| * Returns whether or not there exists a purchase of the given product. | |||
| */ | |||
| public boolean hasPurchase(String sku) { | |||
| return mPurchaseMap.containsKey(sku); | |||
| } | |||
| /** | |||
| * Return whether or not details about the given product are available. | |||
| */ | |||
| public boolean hasDetails(String sku) { | |||
| return mSkuMap.containsKey(sku); | |||
| } | |||
| /** | |||
| * Erase a purchase (locally) from the inventory, given its product ID. This just | |||
| * modifies the Inventory object locally and has no effect on the server! This is | |||
| * useful when you have an existing Inventory object which you know to be up to date, | |||
| * and you have just consumed an item successfully, which means that erasing its | |||
| * purchase data from the Inventory you already have is quicker than querying for | |||
| * a new Inventory. | |||
| */ | |||
| public void erasePurchase(String sku) { | |||
| if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku); | |||
| } | |||
| /** | |||
| * Returns a list of all owned product IDs. | |||
| */ | |||
| List<String> getAllOwnedSkus() { | |||
| return new ArrayList<String>(mPurchaseMap.keySet()); | |||
| } | |||
| /** | |||
| * Returns a list of all owned product IDs of a given type | |||
| */ | |||
| List<String> getAllOwnedSkus(String itemType) { | |||
| List<String> result = new ArrayList<String>(); | |||
| for (Purchase p : mPurchaseMap.values()) { | |||
| if (p.getItemType().equals(itemType)) result.add(p.getSku()); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * Returns a list of all purchases. | |||
| */ | |||
| public List<Purchase> getAllPurchases() { | |||
| return new ArrayList<Purchase>(mPurchaseMap.values()); | |||
| } | |||
| /** | |||
| * Returns a list of all products. | |||
| */ | |||
| public List<SkuDetails> getAllProducts() { | |||
| return new ArrayList<SkuDetails>(mSkuMap.values()); | |||
| } | |||
| void addSkuDetails(SkuDetails d) { | |||
| mSkuMap.put(d.getSku(), d); | |||
| } | |||
| public void addPurchase(Purchase p) { | |||
| mPurchaseMap.put(p.getSku(), p); | |||
| } | |||
| } | |||
| @@ -0,0 +1,63 @@ | |||
| /* Copyright (c) 2012 Google Inc. | |||
| * | |||
| * 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 ir.appeto.myketpayment.util; | |||
| import org.json.JSONException; | |||
| import org.json.JSONObject; | |||
| /** | |||
| * Represents an in-app billing purchase. | |||
| */ | |||
| public class Purchase { | |||
| String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS | |||
| String mOrderId; | |||
| String mPackageName; | |||
| String mSku; | |||
| long mPurchaseTime; | |||
| int mPurchaseState; | |||
| String mDeveloperPayload; | |||
| String mToken; | |||
| String mOriginalJson; | |||
| String mSignature; | |||
| public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException { | |||
| mItemType = itemType; | |||
| mOriginalJson = jsonPurchaseInfo; | |||
| JSONObject o = new JSONObject(mOriginalJson); | |||
| mOrderId = o.optString("orderId"); | |||
| mPackageName = o.optString("packageName"); | |||
| mSku = o.optString("productId"); | |||
| mPurchaseTime = o.optLong("purchaseTime"); | |||
| mPurchaseState = o.optInt("purchaseState"); | |||
| mDeveloperPayload = o.optString("developerPayload"); | |||
| mToken = o.optString("token", o.optString("purchaseToken")); | |||
| mSignature = signature; | |||
| } | |||
| public String getItemType() { return mItemType; } | |||
| public String getOrderId() { return mOrderId; } | |||
| public String getPackageName() { return mPackageName; } | |||
| public String getSku() { return mSku; } | |||
| public long getPurchaseTime() { return mPurchaseTime; } | |||
| public int getPurchaseState() { return mPurchaseState; } | |||
| public String getDeveloperPayload() { return mDeveloperPayload; } | |||
| public String getToken() { return mToken; } | |||
| public String getOriginalJson() { return mOriginalJson; } | |||
| public String getSignature() { return mSignature; } | |||
| @Override | |||
| public String toString() { return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson; } | |||
| } | |||
| @@ -0,0 +1,123 @@ | |||
| /* Copyright (c) 2012 Google Inc. | |||
| * | |||
| * 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 ir.appeto.myketpayment.util; | |||
| import android.text.TextUtils; | |||
| import android.util.Log; | |||
| import org.json.JSONException; | |||
| import org.json.JSONObject; | |||
| import java.security.InvalidKeyException; | |||
| import java.security.KeyFactory; | |||
| import java.security.NoSuchAlgorithmException; | |||
| import java.security.PublicKey; | |||
| import java.security.Signature; | |||
| import java.security.SignatureException; | |||
| import java.security.spec.InvalidKeySpecException; | |||
| import java.security.spec.X509EncodedKeySpec; | |||
| /** | |||
| * Security-related methods. For a secure implementation, all of this code | |||
| * should be implemented on a server that communicates with the | |||
| * application on the device. For the sake of simplicity and clarity of this | |||
| * example, this code is included here and is executed on the device. If you | |||
| * must verify the purchases on the phone, you should obfuscate this code to | |||
| * make it harder for an attacker to replace the code with stubs that treat all | |||
| * purchases as verified. | |||
| */ | |||
| public class Security { | |||
| private static final String TAG = "IABUtil/Security"; | |||
| private static final String KEY_FACTORY_ALGORITHM = "RSA"; | |||
| private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; | |||
| /** | |||
| * Verifies that the data was signed with the given signature, and returns | |||
| * the verified purchase. The data is in JSON format and signed | |||
| * with a private key. The data also contains the {@link PurchaseState} | |||
| * and product ID of the purchase. | |||
| * @param base64PublicKey the base64-encoded public key to use for verifying. | |||
| * @param signedData the signed JSON string (signed, not encrypted) | |||
| * @param signature the signature for the data, signed with the private key | |||
| */ | |||
| public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) { | |||
| if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) || | |||
| TextUtils.isEmpty(signature)) { | |||
| Log.e(TAG, "Purchase verification failed: missing data."); | |||
| return false; | |||
| } | |||
| PublicKey key = Security.generatePublicKey(base64PublicKey); | |||
| return Security.verify(key, signedData, signature); | |||
| } | |||
| /** | |||
| * Generates a PublicKey instance from a string containing the | |||
| * Base64-encoded public key. | |||
| * | |||
| * @param encodedPublicKey Base64-encoded public key | |||
| * @throws IllegalArgumentException if encodedPublicKey is invalid | |||
| */ | |||
| public static PublicKey generatePublicKey(String encodedPublicKey) { | |||
| try { | |||
| byte[] decodedKey = Base64.decode(encodedPublicKey); | |||
| KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM); | |||
| return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); | |||
| } catch (NoSuchAlgorithmException e) { | |||
| throw new RuntimeException(e); | |||
| } catch (InvalidKeySpecException e) { | |||
| Log.e(TAG, "Invalid key specification."); | |||
| throw new IllegalArgumentException(e); | |||
| } catch (Base64DecoderException e) { | |||
| Log.e(TAG, "Base64 decoding failed."); | |||
| throw new IllegalArgumentException(e); | |||
| } | |||
| } | |||
| /** | |||
| * Verifies that the signature from the server matches the computed | |||
| * signature on the data. Returns true if the data is correctly signed. | |||
| * | |||
| * @param publicKey public key associated with the developer account | |||
| * @param signedData signed data from server | |||
| * @param signature server signature | |||
| * @return true if the data and signature match | |||
| */ | |||
| public static boolean verify(PublicKey publicKey, String signedData, String signature) { | |||
| Signature sig; | |||
| try { | |||
| sig = Signature.getInstance(SIGNATURE_ALGORITHM); | |||
| sig.initVerify(publicKey); | |||
| sig.update(signedData.getBytes()); | |||
| if (!sig.verify(Base64.decode(signature))) { | |||
| Log.e(TAG, "Signature verification failed."); | |||
| return false; | |||
| } | |||
| return true; | |||
| } catch (NoSuchAlgorithmException e) { | |||
| Log.e(TAG, "NoSuchAlgorithmException."); | |||
| } catch (InvalidKeyException e) { | |||
| Log.e(TAG, "Invalid key specification."); | |||
| } catch (SignatureException e) { | |||
| Log.e(TAG, "Signature exception."); | |||
| } catch (Base64DecoderException e) { | |||
| Log.e(TAG, "Base64 decoding failed."); | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| @@ -0,0 +1,77 @@ | |||
| /* Copyright (c) 2012 Google Inc. | |||
| * | |||
| * 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 ir.appeto.myketpayment.util; | |||
| import org.json.JSONException; | |||
| import org.json.JSONObject; | |||
| /** | |||
| * Represents an in-app product's listing details. | |||
| */ | |||
| public class SkuDetails { | |||
| String mItemType; | |||
| String mSku; | |||
| String mType; | |||
| String mPrice; | |||
| String mTitle; | |||
| String mDescription; | |||
| String mJson; | |||
| public SkuDetails(String jsonSkuDetails) throws JSONException { | |||
| this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails); | |||
| } | |||
| public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException { | |||
| mItemType = itemType; | |||
| mJson = jsonSkuDetails; | |||
| JSONObject o = new JSONObject(mJson); | |||
| mSku = o.optString("productId"); | |||
| mType = o.optString("type"); | |||
| mPrice = o.optString("price"); | |||
| mTitle = o.optString("title"); | |||
| mDescription = o.optString("description"); | |||
| } | |||
| public String getSku() { | |||
| return mSku; | |||
| } | |||
| public String getType() { | |||
| return mType; | |||
| } | |||
| public String getPrice() { | |||
| return mPrice; | |||
| } | |||
| public String getTitle() { | |||
| return mTitle; | |||
| } | |||
| public String getDescription() { | |||
| return mDescription; | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return "SkuDetails:" + mJson; | |||
| } | |||
| public JSONObject toJson() throws JSONException { | |||
| JSONObject jsonObj = new JSONObject(mJson); | |||
| return jsonObj; | |||
| } | |||
| } | |||
| @@ -0,0 +1,44 @@ | |||
| # Miscellaneous | |||
| *.class | |||
| *.log | |||
| *.pyc | |||
| *.swp | |||
| .DS_Store | |||
| .atom/ | |||
| .buildlog/ | |||
| .history | |||
| .svn/ | |||
| # IntelliJ related | |||
| *.iml | |||
| *.ipr | |||
| *.iws | |||
| .idea/ | |||
| # The .vscode folder contains launch configuration and tasks you configure in | |||
| # VS Code which you may wish to be included in version control, so this line | |||
| # is commented out by default. | |||
| #.vscode/ | |||
| # Flutter/Dart/Pub related | |||
| **/doc/api/ | |||
| **/ios/Flutter/.last_build_id | |||
| .dart_tool/ | |||
| .flutter-plugins | |||
| .flutter-plugins-dependencies | |||
| .packages | |||
| .pub-cache/ | |||
| .pub/ | |||
| /build/ | |||
| # Web related | |||
| lib/generated_plugin_registrant.dart | |||
| # Symbolication related | |||
| app.*.symbols | |||
| # Obfuscation related | |||
| app.*.map.json | |||
| # Exceptions to above rules. | |||
| !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages | |||
| @@ -0,0 +1,10 @@ | |||
| # This file tracks properties of this Flutter project. | |||
| # Used by Flutter tool to assess capabilities and perform upgrades etc. | |||
| # | |||
| # This file should be version controlled and should not be manually edited. | |||
| version: | |||
| revision: c969b8af7b48bd0f4e3329ed3f112f41136d8bcd | |||
| channel: master | |||
| project_type: app | |||
| @@ -0,0 +1,16 @@ | |||
| # myketpayment_example | |||
| Demonstrates how to use the myketpayment plugin. | |||
| ## Getting Started | |||
| This project is a starting point for a Flutter application. | |||
| A few resources to get you started if this is your first Flutter project: | |||
| - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) | |||
| - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) | |||
| For help getting started with Flutter, view our | |||
| [online documentation](https://flutter.dev/docs), which offers tutorials, | |||
| samples, guidance on mobile development, and a full API reference. | |||
| @@ -0,0 +1,7 @@ | |||
| gradle-wrapper.jar | |||
| /.gradle | |||
| /captures/ | |||
| /gradlew | |||
| /gradlew.bat | |||
| /local.properties | |||
| GeneratedPluginRegistrant.java | |||
| @@ -0,0 +1,54 @@ | |||
| def localProperties = new Properties() | |||
| def localPropertiesFile = rootProject.file('local.properties') | |||
| if (localPropertiesFile.exists()) { | |||
| localPropertiesFile.withReader('UTF-8') { reader -> | |||
| localProperties.load(reader) | |||
| } | |||
| } | |||
| def flutterRoot = localProperties.getProperty('flutter.sdk') | |||
| if (flutterRoot == null) { | |||
| throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") | |||
| } | |||
| def flutterVersionCode = localProperties.getProperty('flutter.versionCode') | |||
| if (flutterVersionCode == null) { | |||
| flutterVersionCode = '1' | |||
| } | |||
| def flutterVersionName = localProperties.getProperty('flutter.versionName') | |||
| if (flutterVersionName == null) { | |||
| flutterVersionName = '1.0' | |||
| } | |||
| apply plugin: 'com.android.application' | |||
| apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" | |||
| android { | |||
| compileSdkVersion 28 | |||
| lintOptions { | |||
| disable 'InvalidPackage' | |||
| } | |||
| defaultConfig { | |||
| // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). | |||
| applicationId "ir.appeto.myketpayment_example" | |||
| minSdkVersion 16 | |||
| targetSdkVersion 28 | |||
| versionCode flutterVersionCode.toInteger() | |||
| versionName flutterVersionName | |||
| } | |||
| buildTypes { | |||
| release { | |||
| // TODO: Add your own signing config for the release build. | |||
| // Signing with the debug keys for now, so `flutter run --release` works. | |||
| signingConfig signingConfigs.debug | |||
| } | |||
| } | |||
| } | |||
| flutter { | |||
| source '../..' | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
| package="ir.appeto.myketpayment_example"> | |||
| <!-- Flutter needs it to communicate with the running application | |||
| to allow setting breakpoints, to provide hot reload, etc. | |||
| --> | |||
| <uses-permission android:name="android.permission.INTERNET"/> | |||
| <uses-permission android:name="ir.mservices.market.BILLING" /> | |||
| </manifest> | |||
| @@ -0,0 +1,52 @@ | |||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
| package="ir.appeto.myketpayment_example"> | |||
| <!-- io.flutter.app.FlutterApplication is an android.app.Application that | |||
| calls FlutterMain.startInitialization(this); in its onCreate method. | |||
| In most cases you can leave this as-is, but you if you want to provide | |||
| additional functionality it is fine to subclass or reimplement | |||
| FlutterApplication and put your custom class here. --> | |||
| <uses-permission android:name="ir.mservices.market.BILLING" /> | |||
| <application | |||
| android:name="io.flutter.app.FlutterApplication" | |||
| android:label="myketpayment_example" | |||
| android:icon="@mipmap/ic_launcher"> | |||
| <activity | |||
| android:name=".MainActivity" | |||
| android:launchMode="singleTop" | |||
| android:theme="@style/LaunchTheme" | |||
| android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | |||
| android:hardwareAccelerated="true" | |||
| android:windowSoftInputMode="adjustResize"> | |||
| <!-- Specifies an Android theme to apply to this Activity as soon as | |||
| the Android process has started. This theme is visible to the user | |||
| while the Flutter UI initializes. After that, this theme continues | |||
| to determine the Window background behind the Flutter UI. --> | |||
| <meta-data | |||
| android:name="io.flutter.embedding.android.NormalTheme" | |||
| android:resource="@style/NormalTheme" | |||
| /> | |||
| <!-- Displays an Android View that continues showing the launch screen | |||
| Drawable until Flutter paints its first frame, then this splash | |||
| screen fades out. A splash screen is useful to avoid any visual | |||
| gap between the end of Android's launch screen and the painting of | |||
| Flutter's first frame. --> | |||
| <meta-data | |||
| android:name="io.flutter.embedding.android.SplashScreenDrawable" | |||
| android:resource="@drawable/launch_background" | |||
| /> | |||
| <intent-filter> | |||
| <action android:name="android.intent.action.MAIN"/> | |||
| <category android:name="android.intent.category.LAUNCHER"/> | |||
| </intent-filter> | |||
| </activity> | |||
| <!-- Don't delete the meta-data below. | |||
| This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> | |||
| <meta-data | |||
| android:name="flutterEmbedding" | |||
| android:value="2" /> | |||
| </application> | |||
| </manifest> | |||
| @@ -0,0 +1,6 @@ | |||
| package ir.appeto.myketpayment_example; | |||
| import io.flutter.embedding.android.FlutterActivity; | |||
| public class MainActivity extends FlutterActivity { | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <!-- Modify this file to customize your launch splash screen --> | |||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |||
| <item android:drawable="@android:color/white" /> | |||
| <!-- You can insert your own image assets here --> | |||
| <!-- <item> | |||
| <bitmap | |||
| android:gravity="center" | |||
| android:src="@mipmap/launch_image" /> | |||
| </item> --> | |||
| </layer-list> | |||
| @@ -0,0 +1,18 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <resources> | |||
| <!-- Theme applied to the Android Window while the process is starting --> | |||
| <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> | |||
| <!-- Show a splash screen on the activity. Automatically removed when | |||
| Flutter draws its first frame --> | |||
| <item name="android:windowBackground">@drawable/launch_background</item> | |||
| </style> | |||
| <!-- Theme applied to the Android Window as soon as the process has started. | |||
| This theme determines the color of the Android Window while your | |||
| Flutter UI initializes, as well as behind your Flutter UI while its | |||
| running. | |||
| This Theme is only used starting with V2 of Flutter's Android embedding. --> | |||
| <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> | |||
| <item name="android:windowBackground">@android:color/white</item> | |||
| </style> | |||
| </resources> | |||
| @@ -0,0 +1,7 @@ | |||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
| package="ir.appeto.myketpayment_example"> | |||
| <!-- Flutter needs it to communicate with the running application | |||
| to allow setting breakpoints, to provide hot reload, etc. | |||
| --> | |||
| <uses-permission android:name="android.permission.INTERNET"/> | |||
| </manifest> | |||
| @@ -0,0 +1,29 @@ | |||
| buildscript { | |||
| repositories { | |||
| google() | |||
| jcenter() | |||
| } | |||
| dependencies { | |||
| classpath 'com.android.tools.build:gradle:3.5.0' | |||
| } | |||
| } | |||
| allprojects { | |||
| repositories { | |||
| google() | |||
| jcenter() | |||
| } | |||
| } | |||
| rootProject.buildDir = '../build' | |||
| subprojects { | |||
| project.buildDir = "${rootProject.buildDir}/${project.name}" | |||
| } | |||
| subprojects { | |||
| project.evaluationDependsOn(':app') | |||
| } | |||
| task clean(type: Delete) { | |||
| delete rootProject.buildDir | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| org.gradle.jvmargs=-Xmx1536M | |||
| android.enableR8=true | |||
| android.useAndroidX=true | |||
| android.enableJetifier=true | |||
| @@ -0,0 +1,6 @@ | |||
| #Fri Jun 23 08:50:38 CEST 2017 | |||
| distributionBase=GRADLE_USER_HOME | |||
| distributionPath=wrapper/dists | |||
| zipStoreBase=GRADLE_USER_HOME | |||
| zipStorePath=wrapper/dists | |||
| distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip | |||
| @@ -0,0 +1,15 @@ | |||
| // Copyright 2014 The Flutter Authors. All rights reserved. | |||
| // Use of this source code is governed by a BSD-style license that can be | |||
| // found in the LICENSE file. | |||
| include ':app' | |||
| def localPropertiesFile = new File(rootProject.projectDir, "local.properties") | |||
| def properties = new Properties() | |||
| assert localPropertiesFile.exists() | |||
| localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } | |||
| def flutterSdkPath = properties.getProperty("flutter.sdk") | |||
| assert flutterSdkPath != null, "flutter.sdk not set in local.properties" | |||
| apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" | |||
| @@ -0,0 +1,32 @@ | |||
| *.mode1v3 | |||
| *.mode2v3 | |||
| *.moved-aside | |||
| *.pbxuser | |||
| *.perspectivev3 | |||
| **/*sync/ | |||
| .sconsign.dblite | |||
| .tags* | |||
| **/.vagrant/ | |||
| **/DerivedData/ | |||
| Icon? | |||
| **/Pods/ | |||
| **/.symlinks/ | |||
| profile | |||
| xcuserdata | |||
| **/.generated/ | |||
| Flutter/App.framework | |||
| Flutter/Flutter.framework | |||
| Flutter/Flutter.podspec | |||
| Flutter/Generated.xcconfig | |||
| Flutter/app.flx | |||
| Flutter/app.zip | |||
| Flutter/flutter_assets/ | |||
| Flutter/flutter_export_environment.sh | |||
| ServiceDefinitions.json | |||
| Runner/GeneratedPluginRegistrant.* | |||
| # Exceptions to above rules. | |||
| !default.mode1v3 | |||
| !default.mode2v3 | |||
| !default.pbxuser | |||
| !default.perspectivev3 | |||
| @@ -0,0 +1,26 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>CFBundleDevelopmentRegion</key> | |||
| <string>$(DEVELOPMENT_LANGUAGE)</string> | |||
| <key>CFBundleExecutable</key> | |||
| <string>App</string> | |||
| <key>CFBundleIdentifier</key> | |||
| <string>io.flutter.flutter.app</string> | |||
| <key>CFBundleInfoDictionaryVersion</key> | |||
| <string>6.0</string> | |||
| <key>CFBundleName</key> | |||
| <string>App</string> | |||
| <key>CFBundlePackageType</key> | |||
| <string>FMWK</string> | |||
| <key>CFBundleShortVersionString</key> | |||
| <string>1.0</string> | |||
| <key>CFBundleSignature</key> | |||
| <string>????</string> | |||
| <key>CFBundleVersion</key> | |||
| <string>1.0</string> | |||
| <key>MinimumOSVersion</key> | |||
| <string>8.0</string> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1 @@ | |||
| #include "Generated.xcconfig" | |||
| @@ -0,0 +1 @@ | |||
| #include "Generated.xcconfig" | |||
| @@ -0,0 +1,496 @@ | |||
| // !$*UTF8*$! | |||
| { | |||
| archiveVersion = 1; | |||
| classes = { | |||
| }; | |||
| objectVersion = 46; | |||
| objects = { | |||
| /* Begin PBXBuildFile section */ | |||
| 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; | |||
| 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; | |||
| 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; | |||
| 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; | |||
| 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; | |||
| 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; | |||
| 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; | |||
| /* End PBXBuildFile section */ | |||
| /* Begin PBXCopyFilesBuildPhase section */ | |||
| 9705A1C41CF9048500538489 /* Embed Frameworks */ = { | |||
| isa = PBXCopyFilesBuildPhase; | |||
| buildActionMask = 2147483647; | |||
| dstPath = ""; | |||
| dstSubfolderSpec = 10; | |||
| files = ( | |||
| ); | |||
| name = "Embed Frameworks"; | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| /* End PBXCopyFilesBuildPhase section */ | |||
| /* Begin PBXFileReference section */ | |||
| 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; | |||
| 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; | |||
| 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | |||
| 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; | |||
| 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; | |||
| 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; | |||
| 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; | |||
| 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; | |||
| 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
| 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; | |||
| 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; | |||
| 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; | |||
| 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; | |||
| 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | |||
| /* End PBXFileReference section */ | |||
| /* Begin PBXFrameworksBuildPhase section */ | |||
| 97C146EB1CF9000F007C117D /* Frameworks */ = { | |||
| isa = PBXFrameworksBuildPhase; | |||
| buildActionMask = 2147483647; | |||
| files = ( | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| /* End PBXFrameworksBuildPhase section */ | |||
| /* Begin PBXGroup section */ | |||
| 9740EEB11CF90186004384FC /* Flutter */ = { | |||
| isa = PBXGroup; | |||
| children = ( | |||
| 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, | |||
| 9740EEB21CF90195004384FC /* Debug.xcconfig */, | |||
| 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, | |||
| 9740EEB31CF90195004384FC /* Generated.xcconfig */, | |||
| ); | |||
| name = Flutter; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| 97C146E51CF9000F007C117D = { | |||
| isa = PBXGroup; | |||
| children = ( | |||
| 9740EEB11CF90186004384FC /* Flutter */, | |||
| 97C146F01CF9000F007C117D /* Runner */, | |||
| 97C146EF1CF9000F007C117D /* Products */, | |||
| CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, | |||
| ); | |||
| sourceTree = "<group>"; | |||
| }; | |||
| 97C146EF1CF9000F007C117D /* Products */ = { | |||
| isa = PBXGroup; | |||
| children = ( | |||
| 97C146EE1CF9000F007C117D /* Runner.app */, | |||
| ); | |||
| name = Products; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| 97C146F01CF9000F007C117D /* Runner */ = { | |||
| isa = PBXGroup; | |||
| children = ( | |||
| 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, | |||
| 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, | |||
| 97C146FA1CF9000F007C117D /* Main.storyboard */, | |||
| 97C146FD1CF9000F007C117D /* Assets.xcassets */, | |||
| 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, | |||
| 97C147021CF9000F007C117D /* Info.plist */, | |||
| 97C146F11CF9000F007C117D /* Supporting Files */, | |||
| 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, | |||
| 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, | |||
| ); | |||
| path = Runner; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| 97C146F11CF9000F007C117D /* Supporting Files */ = { | |||
| isa = PBXGroup; | |||
| children = ( | |||
| 97C146F21CF9000F007C117D /* main.m */, | |||
| ); | |||
| name = "Supporting Files"; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| /* End PBXGroup section */ | |||
| /* Begin PBXNativeTarget section */ | |||
| 97C146ED1CF9000F007C117D /* Runner */ = { | |||
| isa = PBXNativeTarget; | |||
| buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; | |||
| buildPhases = ( | |||
| 9740EEB61CF901F6004384FC /* Run Script */, | |||
| 97C146EA1CF9000F007C117D /* Sources */, | |||
| 97C146EB1CF9000F007C117D /* Frameworks */, | |||
| 97C146EC1CF9000F007C117D /* Resources */, | |||
| 9705A1C41CF9048500538489 /* Embed Frameworks */, | |||
| 3B06AD1E1E4923F5004D2608 /* Thin Binary */, | |||
| ); | |||
| buildRules = ( | |||
| ); | |||
| dependencies = ( | |||
| ); | |||
| name = Runner; | |||
| productName = Runner; | |||
| productReference = 97C146EE1CF9000F007C117D /* Runner.app */; | |||
| productType = "com.apple.product-type.application"; | |||
| }; | |||
| /* End PBXNativeTarget section */ | |||
| /* Begin PBXProject section */ | |||
| 97C146E61CF9000F007C117D /* Project object */ = { | |||
| isa = PBXProject; | |||
| attributes = { | |||
| LastUpgradeCheck = 1020; | |||
| ORGANIZATIONNAME = ""; | |||
| TargetAttributes = { | |||
| 97C146ED1CF9000F007C117D = { | |||
| CreatedOnToolsVersion = 7.3.1; | |||
| }; | |||
| }; | |||
| }; | |||
| buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; | |||
| compatibilityVersion = "Xcode 9.3"; | |||
| developmentRegion = en; | |||
| hasScannedForEncodings = 0; | |||
| knownRegions = ( | |||
| en, | |||
| Base, | |||
| ); | |||
| mainGroup = 97C146E51CF9000F007C117D; | |||
| productRefGroup = 97C146EF1CF9000F007C117D /* Products */; | |||
| projectDirPath = ""; | |||
| projectRoot = ""; | |||
| targets = ( | |||
| 97C146ED1CF9000F007C117D /* Runner */, | |||
| ); | |||
| }; | |||
| /* End PBXProject section */ | |||
| /* Begin PBXResourcesBuildPhase section */ | |||
| 97C146EC1CF9000F007C117D /* Resources */ = { | |||
| isa = PBXResourcesBuildPhase; | |||
| buildActionMask = 2147483647; | |||
| files = ( | |||
| 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, | |||
| 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, | |||
| 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, | |||
| 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| /* End PBXResourcesBuildPhase section */ | |||
| /* Begin PBXShellScriptBuildPhase section */ | |||
| 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { | |||
| isa = PBXShellScriptBuildPhase; | |||
| buildActionMask = 2147483647; | |||
| files = ( | |||
| ); | |||
| inputPaths = ( | |||
| ); | |||
| name = "Thin Binary"; | |||
| outputPaths = ( | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| shellPath = /bin/sh; | |||
| shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; | |||
| }; | |||
| 9740EEB61CF901F6004384FC /* Run Script */ = { | |||
| isa = PBXShellScriptBuildPhase; | |||
| buildActionMask = 2147483647; | |||
| files = ( | |||
| ); | |||
| inputPaths = ( | |||
| ); | |||
| name = "Run Script"; | |||
| outputPaths = ( | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| shellPath = /bin/sh; | |||
| shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; | |||
| }; | |||
| /* End PBXShellScriptBuildPhase section */ | |||
| /* Begin PBXSourcesBuildPhase section */ | |||
| 97C146EA1CF9000F007C117D /* Sources */ = { | |||
| isa = PBXSourcesBuildPhase; | |||
| buildActionMask = 2147483647; | |||
| files = ( | |||
| 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, | |||
| 97C146F31CF9000F007C117D /* main.m in Sources */, | |||
| 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| /* End PBXSourcesBuildPhase section */ | |||
| /* Begin PBXVariantGroup section */ | |||
| 97C146FA1CF9000F007C117D /* Main.storyboard */ = { | |||
| isa = PBXVariantGroup; | |||
| children = ( | |||
| 97C146FB1CF9000F007C117D /* Base */, | |||
| ); | |||
| name = Main.storyboard; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { | |||
| isa = PBXVariantGroup; | |||
| children = ( | |||
| 97C147001CF9000F007C117D /* Base */, | |||
| ); | |||
| name = LaunchScreen.storyboard; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| /* End PBXVariantGroup section */ | |||
| /* Begin XCBuildConfiguration section */ | |||
| 249021D3217E4FDB00AE95B9 /* Profile */ = { | |||
| isa = XCBuildConfiguration; | |||
| buildSettings = { | |||
| ALWAYS_SEARCH_USER_PATHS = NO; | |||
| CLANG_ANALYZER_NONNULL = YES; | |||
| CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | |||
| CLANG_CXX_LIBRARY = "libc++"; | |||
| CLANG_ENABLE_MODULES = YES; | |||
| CLANG_ENABLE_OBJC_ARC = YES; | |||
| CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | |||
| CLANG_WARN_BOOL_CONVERSION = YES; | |||
| CLANG_WARN_COMMA = YES; | |||
| CLANG_WARN_CONSTANT_CONVERSION = YES; | |||
| CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | |||
| CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |||
| CLANG_WARN_EMPTY_BODY = YES; | |||
| CLANG_WARN_ENUM_CONVERSION = YES; | |||
| CLANG_WARN_INFINITE_RECURSION = YES; | |||
| CLANG_WARN_INT_CONVERSION = YES; | |||
| CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | |||
| CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | |||
| CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | |||
| CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |||
| CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | |||
| CLANG_WARN_STRICT_PROTOTYPES = YES; | |||
| CLANG_WARN_SUSPICIOUS_MOVE = YES; | |||
| CLANG_WARN_UNREACHABLE_CODE = YES; | |||
| CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |||
| "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | |||
| COPY_PHASE_STRIP = NO; | |||
| DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | |||
| ENABLE_NS_ASSERTIONS = NO; | |||
| ENABLE_STRICT_OBJC_MSGSEND = YES; | |||
| GCC_C_LANGUAGE_STANDARD = gnu99; | |||
| GCC_NO_COMMON_BLOCKS = YES; | |||
| GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |||
| GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |||
| GCC_WARN_UNDECLARED_SELECTOR = YES; | |||
| GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |||
| GCC_WARN_UNUSED_FUNCTION = YES; | |||
| GCC_WARN_UNUSED_VARIABLE = YES; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||
| MTL_ENABLE_DEBUG_INFO = NO; | |||
| SDKROOT = iphoneos; | |||
| SUPPORTED_PLATFORMS = iphoneos; | |||
| TARGETED_DEVICE_FAMILY = "1,2"; | |||
| VALIDATE_PRODUCT = YES; | |||
| }; | |||
| name = Profile; | |||
| }; | |||
| 249021D4217E4FDB00AE95B9 /* Profile */ = { | |||
| isa = XCBuildConfiguration; | |||
| baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | |||
| buildSettings = { | |||
| ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |||
| CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | |||
| ENABLE_BITCODE = NO; | |||
| FRAMEWORK_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| INFOPLIST_FILE = Runner/Info.plist; | |||
| LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | |||
| LIBRARY_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| PRODUCT_BUNDLE_IDENTIFIER = ir.appeto.myketpaymentExample; | |||
| PRODUCT_NAME = "$(TARGET_NAME)"; | |||
| VERSIONING_SYSTEM = "apple-generic"; | |||
| }; | |||
| name = Profile; | |||
| }; | |||
| 97C147031CF9000F007C117D /* Debug */ = { | |||
| isa = XCBuildConfiguration; | |||
| buildSettings = { | |||
| ALWAYS_SEARCH_USER_PATHS = NO; | |||
| CLANG_ANALYZER_NONNULL = YES; | |||
| CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | |||
| CLANG_CXX_LIBRARY = "libc++"; | |||
| CLANG_ENABLE_MODULES = YES; | |||
| CLANG_ENABLE_OBJC_ARC = YES; | |||
| CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | |||
| CLANG_WARN_BOOL_CONVERSION = YES; | |||
| CLANG_WARN_COMMA = YES; | |||
| CLANG_WARN_CONSTANT_CONVERSION = YES; | |||
| CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | |||
| CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |||
| CLANG_WARN_EMPTY_BODY = YES; | |||
| CLANG_WARN_ENUM_CONVERSION = YES; | |||
| CLANG_WARN_INFINITE_RECURSION = YES; | |||
| CLANG_WARN_INT_CONVERSION = YES; | |||
| CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | |||
| CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | |||
| CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | |||
| CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |||
| CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | |||
| CLANG_WARN_STRICT_PROTOTYPES = YES; | |||
| CLANG_WARN_SUSPICIOUS_MOVE = YES; | |||
| CLANG_WARN_UNREACHABLE_CODE = YES; | |||
| CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |||
| "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | |||
| COPY_PHASE_STRIP = NO; | |||
| DEBUG_INFORMATION_FORMAT = dwarf; | |||
| ENABLE_STRICT_OBJC_MSGSEND = YES; | |||
| ENABLE_TESTABILITY = YES; | |||
| GCC_C_LANGUAGE_STANDARD = gnu99; | |||
| GCC_DYNAMIC_NO_PIC = NO; | |||
| GCC_NO_COMMON_BLOCKS = YES; | |||
| GCC_OPTIMIZATION_LEVEL = 0; | |||
| GCC_PREPROCESSOR_DEFINITIONS = ( | |||
| "DEBUG=1", | |||
| "$(inherited)", | |||
| ); | |||
| GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |||
| GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |||
| GCC_WARN_UNDECLARED_SELECTOR = YES; | |||
| GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |||
| GCC_WARN_UNUSED_FUNCTION = YES; | |||
| GCC_WARN_UNUSED_VARIABLE = YES; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||
| MTL_ENABLE_DEBUG_INFO = YES; | |||
| ONLY_ACTIVE_ARCH = YES; | |||
| SDKROOT = iphoneos; | |||
| TARGETED_DEVICE_FAMILY = "1,2"; | |||
| }; | |||
| name = Debug; | |||
| }; | |||
| 97C147041CF9000F007C117D /* Release */ = { | |||
| isa = XCBuildConfiguration; | |||
| buildSettings = { | |||
| ALWAYS_SEARCH_USER_PATHS = NO; | |||
| CLANG_ANALYZER_NONNULL = YES; | |||
| CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | |||
| CLANG_CXX_LIBRARY = "libc++"; | |||
| CLANG_ENABLE_MODULES = YES; | |||
| CLANG_ENABLE_OBJC_ARC = YES; | |||
| CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | |||
| CLANG_WARN_BOOL_CONVERSION = YES; | |||
| CLANG_WARN_COMMA = YES; | |||
| CLANG_WARN_CONSTANT_CONVERSION = YES; | |||
| CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | |||
| CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |||
| CLANG_WARN_EMPTY_BODY = YES; | |||
| CLANG_WARN_ENUM_CONVERSION = YES; | |||
| CLANG_WARN_INFINITE_RECURSION = YES; | |||
| CLANG_WARN_INT_CONVERSION = YES; | |||
| CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | |||
| CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | |||
| CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | |||
| CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |||
| CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | |||
| CLANG_WARN_STRICT_PROTOTYPES = YES; | |||
| CLANG_WARN_SUSPICIOUS_MOVE = YES; | |||
| CLANG_WARN_UNREACHABLE_CODE = YES; | |||
| CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |||
| "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | |||
| COPY_PHASE_STRIP = NO; | |||
| DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | |||
| ENABLE_NS_ASSERTIONS = NO; | |||
| ENABLE_STRICT_OBJC_MSGSEND = YES; | |||
| GCC_C_LANGUAGE_STANDARD = gnu99; | |||
| GCC_NO_COMMON_BLOCKS = YES; | |||
| GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |||
| GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |||
| GCC_WARN_UNDECLARED_SELECTOR = YES; | |||
| GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |||
| GCC_WARN_UNUSED_FUNCTION = YES; | |||
| GCC_WARN_UNUSED_VARIABLE = YES; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||
| MTL_ENABLE_DEBUG_INFO = NO; | |||
| SDKROOT = iphoneos; | |||
| SUPPORTED_PLATFORMS = iphoneos; | |||
| TARGETED_DEVICE_FAMILY = "1,2"; | |||
| VALIDATE_PRODUCT = YES; | |||
| }; | |||
| name = Release; | |||
| }; | |||
| 97C147061CF9000F007C117D /* Debug */ = { | |||
| isa = XCBuildConfiguration; | |||
| baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; | |||
| buildSettings = { | |||
| ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |||
| CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | |||
| ENABLE_BITCODE = NO; | |||
| FRAMEWORK_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| INFOPLIST_FILE = Runner/Info.plist; | |||
| LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | |||
| LIBRARY_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| PRODUCT_BUNDLE_IDENTIFIER = ir.appeto.myketpaymentExample; | |||
| PRODUCT_NAME = "$(TARGET_NAME)"; | |||
| VERSIONING_SYSTEM = "apple-generic"; | |||
| }; | |||
| name = Debug; | |||
| }; | |||
| 97C147071CF9000F007C117D /* Release */ = { | |||
| isa = XCBuildConfiguration; | |||
| baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | |||
| buildSettings = { | |||
| ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |||
| CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | |||
| ENABLE_BITCODE = NO; | |||
| FRAMEWORK_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| INFOPLIST_FILE = Runner/Info.plist; | |||
| LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; | |||
| LIBRARY_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| PRODUCT_BUNDLE_IDENTIFIER = ir.appeto.myketpaymentExample; | |||
| PRODUCT_NAME = "$(TARGET_NAME)"; | |||
| VERSIONING_SYSTEM = "apple-generic"; | |||
| }; | |||
| name = Release; | |||
| }; | |||
| /* End XCBuildConfiguration section */ | |||
| /* Begin XCConfigurationList section */ | |||
| 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { | |||
| isa = XCConfigurationList; | |||
| buildConfigurations = ( | |||
| 97C147031CF9000F007C117D /* Debug */, | |||
| 97C147041CF9000F007C117D /* Release */, | |||
| 249021D3217E4FDB00AE95B9 /* Profile */, | |||
| ); | |||
| defaultConfigurationIsVisible = 0; | |||
| defaultConfigurationName = Release; | |||
| }; | |||
| 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { | |||
| isa = XCConfigurationList; | |||
| buildConfigurations = ( | |||
| 97C147061CF9000F007C117D /* Debug */, | |||
| 97C147071CF9000F007C117D /* Release */, | |||
| 249021D4217E4FDB00AE95B9 /* Profile */, | |||
| ); | |||
| defaultConfigurationIsVisible = 0; | |||
| defaultConfigurationName = Release; | |||
| }; | |||
| /* End XCConfigurationList section */ | |||
| }; | |||
| rootObject = 97C146E61CF9000F007C117D /* Project object */; | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <Workspace | |||
| version = "1.0"> | |||
| <FileRef | |||
| location = "group:Runner.xcodeproj"> | |||
| </FileRef> | |||
| </Workspace> | |||
| @@ -0,0 +1,8 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>IDEDidComputeMac32BitWarning</key> | |||
| <true/> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1,8 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>PreviewsEnabled</key> | |||
| <false/> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1,91 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <Scheme | |||
| LastUpgradeVersion = "1020" | |||
| version = "1.3"> | |||
| <BuildAction | |||
| parallelizeBuildables = "YES" | |||
| buildImplicitDependencies = "YES"> | |||
| <BuildActionEntries> | |||
| <BuildActionEntry | |||
| buildForTesting = "YES" | |||
| buildForRunning = "YES" | |||
| buildForProfiling = "YES" | |||
| buildForArchiving = "YES" | |||
| buildForAnalyzing = "YES"> | |||
| <BuildableReference | |||
| BuildableIdentifier = "primary" | |||
| BlueprintIdentifier = "97C146ED1CF9000F007C117D" | |||
| BuildableName = "Runner.app" | |||
| BlueprintName = "Runner" | |||
| ReferencedContainer = "container:Runner.xcodeproj"> | |||
| </BuildableReference> | |||
| </BuildActionEntry> | |||
| </BuildActionEntries> | |||
| </BuildAction> | |||
| <TestAction | |||
| buildConfiguration = "Debug" | |||
| selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | |||
| selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | |||
| shouldUseLaunchSchemeArgsEnv = "YES"> | |||
| <Testables> | |||
| </Testables> | |||
| <MacroExpansion> | |||
| <BuildableReference | |||
| BuildableIdentifier = "primary" | |||
| BlueprintIdentifier = "97C146ED1CF9000F007C117D" | |||
| BuildableName = "Runner.app" | |||
| BlueprintName = "Runner" | |||
| ReferencedContainer = "container:Runner.xcodeproj"> | |||
| </BuildableReference> | |||
| </MacroExpansion> | |||
| <AdditionalOptions> | |||
| </AdditionalOptions> | |||
| </TestAction> | |||
| <LaunchAction | |||
| buildConfiguration = "Debug" | |||
| selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | |||
| selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | |||
| launchStyle = "0" | |||
| useCustomWorkingDirectory = "NO" | |||
| ignoresPersistentStateOnLaunch = "NO" | |||
| debugDocumentVersioning = "YES" | |||
| debugServiceExtension = "internal" | |||
| allowLocationSimulation = "YES"> | |||
| <BuildableProductRunnable | |||
| runnableDebuggingMode = "0"> | |||
| <BuildableReference | |||
| BuildableIdentifier = "primary" | |||
| BlueprintIdentifier = "97C146ED1CF9000F007C117D" | |||
| BuildableName = "Runner.app" | |||
| BlueprintName = "Runner" | |||
| ReferencedContainer = "container:Runner.xcodeproj"> | |||
| </BuildableReference> | |||
| </BuildableProductRunnable> | |||
| <AdditionalOptions> | |||
| </AdditionalOptions> | |||
| </LaunchAction> | |||
| <ProfileAction | |||
| buildConfiguration = "Profile" | |||
| shouldUseLaunchSchemeArgsEnv = "YES" | |||
| savedToolIdentifier = "" | |||
| useCustomWorkingDirectory = "NO" | |||
| debugDocumentVersioning = "YES"> | |||
| <BuildableProductRunnable | |||
| runnableDebuggingMode = "0"> | |||
| <BuildableReference | |||
| BuildableIdentifier = "primary" | |||
| BlueprintIdentifier = "97C146ED1CF9000F007C117D" | |||
| BuildableName = "Runner.app" | |||
| BlueprintName = "Runner" | |||
| ReferencedContainer = "container:Runner.xcodeproj"> | |||
| </BuildableReference> | |||
| </BuildableProductRunnable> | |||
| </ProfileAction> | |||
| <AnalyzeAction | |||
| buildConfiguration = "Debug"> | |||
| </AnalyzeAction> | |||
| <ArchiveAction | |||
| buildConfiguration = "Release" | |||
| revealArchiveInOrganizer = "YES"> | |||
| </ArchiveAction> | |||
| </Scheme> | |||
| @@ -0,0 +1,7 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <Workspace | |||
| version = "1.0"> | |||
| <FileRef | |||
| location = "group:Runner.xcodeproj"> | |||
| </FileRef> | |||
| </Workspace> | |||
| @@ -0,0 +1,8 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>IDEDidComputeMac32BitWarning</key> | |||
| <true/> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1,8 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>PreviewsEnabled</key> | |||
| <false/> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1,6 @@ | |||
| #import <Flutter/Flutter.h> | |||
| #import <UIKit/UIKit.h> | |||
| @interface AppDelegate : FlutterAppDelegate | |||
| @end | |||
| @@ -0,0 +1,13 @@ | |||
| #import "AppDelegate.h" | |||
| #import "GeneratedPluginRegistrant.h" | |||
| @implementation AppDelegate | |||
| - (BOOL)application:(UIApplication *)application | |||
| didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | |||
| [GeneratedPluginRegistrant registerWithRegistry:self]; | |||
| // Override point for customization after application launch. | |||
| return [super application:application didFinishLaunchingWithOptions:launchOptions]; | |||
| } | |||
| @end | |||
| @@ -0,0 +1,122 @@ | |||
| { | |||
| "images" : [ | |||
| { | |||
| "size" : "20x20", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-20x20@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "20x20", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-20x20@3x.png", | |||
| "scale" : "3x" | |||
| }, | |||
| { | |||
| "size" : "29x29", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-29x29@1x.png", | |||
| "scale" : "1x" | |||
| }, | |||
| { | |||
| "size" : "29x29", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-29x29@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "29x29", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-29x29@3x.png", | |||
| "scale" : "3x" | |||
| }, | |||
| { | |||
| "size" : "40x40", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-40x40@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "40x40", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-40x40@3x.png", | |||
| "scale" : "3x" | |||
| }, | |||
| { | |||
| "size" : "60x60", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-60x60@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "60x60", | |||
| "idiom" : "iphone", | |||
| "filename" : "Icon-App-60x60@3x.png", | |||
| "scale" : "3x" | |||
| }, | |||
| { | |||
| "size" : "20x20", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-20x20@1x.png", | |||
| "scale" : "1x" | |||
| }, | |||
| { | |||
| "size" : "20x20", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-20x20@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "29x29", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-29x29@1x.png", | |||
| "scale" : "1x" | |||
| }, | |||
| { | |||
| "size" : "29x29", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-29x29@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "40x40", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-40x40@1x.png", | |||
| "scale" : "1x" | |||
| }, | |||
| { | |||
| "size" : "40x40", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-40x40@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "76x76", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-76x76@1x.png", | |||
| "scale" : "1x" | |||
| }, | |||
| { | |||
| "size" : "76x76", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-76x76@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "83.5x83.5", | |||
| "idiom" : "ipad", | |||
| "filename" : "Icon-App-83.5x83.5@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "size" : "1024x1024", | |||
| "idiom" : "ios-marketing", | |||
| "filename" : "Icon-App-1024x1024@1x.png", | |||
| "scale" : "1x" | |||
| } | |||
| ], | |||
| "info" : { | |||
| "version" : 1, | |||
| "author" : "xcode" | |||
| } | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| { | |||
| "images" : [ | |||
| { | |||
| "idiom" : "universal", | |||
| "filename" : "LaunchImage.png", | |||
| "scale" : "1x" | |||
| }, | |||
| { | |||
| "idiom" : "universal", | |||
| "filename" : "LaunchImage@2x.png", | |||
| "scale" : "2x" | |||
| }, | |||
| { | |||
| "idiom" : "universal", | |||
| "filename" : "LaunchImage@3x.png", | |||
| "scale" : "3x" | |||
| } | |||
| ], | |||
| "info" : { | |||
| "version" : 1, | |||
| "author" : "xcode" | |||
| } | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| # Launch Screen Assets | |||
| You can customize the launch screen with your own desired assets by replacing the image files in this directory. | |||
| You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. | |||
| @@ -0,0 +1,37 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | |||
| <dependencies> | |||
| <deployment identifier="iOS"/> | |||
| <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> | |||
| </dependencies> | |||
| <scenes> | |||
| <!--View Controller--> | |||
| <scene sceneID="EHf-IW-A2E"> | |||
| <objects> | |||
| <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | |||
| <layoutGuides> | |||
| <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> | |||
| <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> | |||
| </layoutGuides> | |||
| <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | |||
| <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | |||
| <subviews> | |||
| <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> | |||
| </imageView> | |||
| </subviews> | |||
| <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | |||
| <constraints> | |||
| <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> | |||
| <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> | |||
| </constraints> | |||
| </view> | |||
| </viewController> | |||
| <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | |||
| </objects> | |||
| <point key="canvasLocation" x="53" y="375"/> | |||
| </scene> | |||
| </scenes> | |||
| <resources> | |||
| <image name="LaunchImage" width="168" height="185"/> | |||
| </resources> | |||
| </document> | |||
| @@ -0,0 +1,26 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> | |||
| <dependencies> | |||
| <deployment identifier="iOS"/> | |||
| <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> | |||
| </dependencies> | |||
| <scenes> | |||
| <!--Flutter View Controller--> | |||
| <scene sceneID="tne-QT-ifu"> | |||
| <objects> | |||
| <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> | |||
| <layoutGuides> | |||
| <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> | |||
| <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> | |||
| </layoutGuides> | |||
| <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> | |||
| <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> | |||
| <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | |||
| <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> | |||
| </view> | |||
| </viewController> | |||
| <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> | |||
| </objects> | |||
| </scene> | |||
| </scenes> | |||
| </document> | |||
| @@ -0,0 +1,45 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>CFBundleDevelopmentRegion</key> | |||
| <string>$(DEVELOPMENT_LANGUAGE)</string> | |||
| <key>CFBundleExecutable</key> | |||
| <string>$(EXECUTABLE_NAME)</string> | |||
| <key>CFBundleIdentifier</key> | |||
| <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | |||
| <key>CFBundleInfoDictionaryVersion</key> | |||
| <string>6.0</string> | |||
| <key>CFBundleName</key> | |||
| <string>myketpayment_example</string> | |||
| <key>CFBundlePackageType</key> | |||
| <string>APPL</string> | |||
| <key>CFBundleShortVersionString</key> | |||
| <string>$(FLUTTER_BUILD_NAME)</string> | |||
| <key>CFBundleSignature</key> | |||
| <string>????</string> | |||
| <key>CFBundleVersion</key> | |||
| <string>$(FLUTTER_BUILD_NUMBER)</string> | |||
| <key>LSRequiresIPhoneOS</key> | |||
| <true/> | |||
| <key>UILaunchStoryboardName</key> | |||
| <string>LaunchScreen</string> | |||
| <key>UIMainStoryboardFile</key> | |||
| <string>Main</string> | |||
| <key>UISupportedInterfaceOrientations</key> | |||
| <array> | |||
| <string>UIInterfaceOrientationPortrait</string> | |||
| <string>UIInterfaceOrientationLandscapeLeft</string> | |||
| <string>UIInterfaceOrientationLandscapeRight</string> | |||
| </array> | |||
| <key>UISupportedInterfaceOrientations~ipad</key> | |||
| <array> | |||
| <string>UIInterfaceOrientationPortrait</string> | |||
| <string>UIInterfaceOrientationPortraitUpsideDown</string> | |||
| <string>UIInterfaceOrientationLandscapeLeft</string> | |||
| <string>UIInterfaceOrientationLandscapeRight</string> | |||
| </array> | |||
| <key>UIViewControllerBasedStatusBarAppearance</key> | |||
| <false/> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1,9 @@ | |||
| #import <Flutter/Flutter.h> | |||
| #import <UIKit/UIKit.h> | |||
| #import "AppDelegate.h" | |||
| int main(int argc, char* argv[]) { | |||
| @autoreleasepool { | |||
| return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); | |||
| } | |||
| } | |||
| @@ -0,0 +1,87 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'dart:async'; | |||
| import 'package:flutter/services.dart'; | |||
| import 'package:myketpayment/myketpayment.dart'; | |||
| void main() { | |||
| runApp(MyApp()); | |||
| } | |||
| class MyApp extends StatefulWidget { | |||
| @override | |||
| _MyAppState createState() => _MyAppState(); | |||
| } | |||
| class _MyAppState extends State<MyApp> { | |||
| String _platformVersion = 'Unknown'; | |||
| @override | |||
| void initState() { | |||
| super.initState(); | |||
| } | |||
| final String rsa = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPBy3LGWCeF5AwPIVdS6DvkTHkS9qa45vNhpZiJTjELjG1VLa9a8nAsm4E6qqKoQ6wh5Cuq3T9NqdtkTwWtLgVYvTl6JQlkN/2XfabkWcn58f14mvrkVv8qHUFr0m/kqz9sp/fk1KvS16BjVy/M3ScuvLr0ONJ+HS5PQvHUTdDLQIDAQAB"; | |||
| bool setup = false; | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return MaterialApp( | |||
| home: Scaffold( | |||
| appBar: AppBar( | |||
| title: const Text('Plugin example app'), | |||
| ), | |||
| body: Center( | |||
| child: Column( | |||
| children: [ | |||
| Text('myket for appeto'), | |||
| SizedBox(height: 20,), | |||
| FlatButton( | |||
| child: Text("buy and consume"), | |||
| onPressed: () async { | |||
| if(!setup) { | |||
| setup = await Myketpayment.setup(rsa); | |||
| } | |||
| print("setup: $setup"); | |||
| if(setup) { | |||
| final result = await Myketpayment.buy(sku: 'myflutter', consume: true); | |||
| afterPurchase(result); | |||
| } | |||
| else { | |||
| print("can not connect to myket"); | |||
| } | |||
| }, | |||
| ), | |||
| SizedBox(height: 20,), | |||
| FlatButton( | |||
| child: Text("buy unlimit"), | |||
| onPressed: () async { | |||
| if(!setup) { | |||
| setup = await Myketpayment.setup(rsa); | |||
| } | |||
| print("setup: $setup"); | |||
| if(setup) { | |||
| final result = await Myketpayment.buy(sku: 'flunlimit'); | |||
| afterPurchase(result); | |||
| } | |||
| else { | |||
| print("can not connect to myket"); | |||
| } | |||
| }, | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| void afterPurchase(Map result) { | |||
| if(result.containsKey('purchased') && result['purchased'] == true) { | |||
| print("purchase info: $result"); | |||
| } | |||
| else { | |||
| print("no purchase: $result"); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,154 @@ | |||
| # Generated by pub | |||
| # See https://dart.dev/tools/pub/glossary#lockfile | |||
| packages: | |||
| async: | |||
| dependency: transitive | |||
| description: | |||
| name: async | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.4.1" | |||
| boolean_selector: | |||
| dependency: transitive | |||
| description: | |||
| name: boolean_selector | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.0" | |||
| charcode: | |||
| dependency: transitive | |||
| description: | |||
| name: charcode | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.3" | |||
| clock: | |||
| dependency: transitive | |||
| description: | |||
| name: clock | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.1" | |||
| collection: | |||
| dependency: transitive | |||
| description: | |||
| name: collection | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.14.12" | |||
| cupertino_icons: | |||
| dependency: "direct main" | |||
| description: | |||
| name: cupertino_icons | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.1.3" | |||
| fake_async: | |||
| dependency: transitive | |||
| description: | |||
| name: fake_async | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.0" | |||
| flutter: | |||
| dependency: "direct main" | |||
| description: flutter | |||
| source: sdk | |||
| version: "0.0.0" | |||
| flutter_test: | |||
| dependency: "direct dev" | |||
| description: flutter | |||
| source: sdk | |||
| version: "0.0.0" | |||
| matcher: | |||
| dependency: transitive | |||
| description: | |||
| name: matcher | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.12.6" | |||
| meta: | |||
| dependency: transitive | |||
| description: | |||
| name: meta | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.8" | |||
| myketpayment: | |||
| dependency: "direct main" | |||
| description: | |||
| path: ".." | |||
| relative: true | |||
| source: path | |||
| version: "0.0.1" | |||
| path: | |||
| dependency: transitive | |||
| description: | |||
| name: path | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.7.0" | |||
| sky_engine: | |||
| dependency: transitive | |||
| description: flutter | |||
| source: sdk | |||
| version: "0.0.99" | |||
| source_span: | |||
| dependency: transitive | |||
| description: | |||
| name: source_span | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.7.0" | |||
| stack_trace: | |||
| dependency: transitive | |||
| description: | |||
| name: stack_trace | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.9.3" | |||
| stream_channel: | |||
| dependency: transitive | |||
| description: | |||
| name: stream_channel | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.0" | |||
| string_scanner: | |||
| dependency: transitive | |||
| description: | |||
| name: string_scanner | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.5" | |||
| term_glyph: | |||
| dependency: transitive | |||
| description: | |||
| name: term_glyph | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.0" | |||
| test_api: | |||
| dependency: transitive | |||
| description: | |||
| name: test_api | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.2.15" | |||
| typed_data: | |||
| dependency: transitive | |||
| description: | |||
| name: typed_data | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.6" | |||
| vector_math: | |||
| dependency: transitive | |||
| description: | |||
| name: vector_math | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.8" | |||
| sdks: | |||
| dart: ">=2.7.0 <3.0.0" | |||
| flutter: ">=1.10.0" | |||
| @@ -0,0 +1,71 @@ | |||
| name: myketpayment_example | |||
| description: Add myket in app purchase for appeto team. | |||
| # The following line prevents the package from being accidentally published to | |||
| # pub.dev using `pub publish`. This is preferred for private packages. | |||
| publish_to: 'none' # Remove this line if you wish to publish to pub.dev | |||
| environment: | |||
| sdk: ">=2.7.0 <3.0.0" | |||
| dependencies: | |||
| flutter: | |||
| sdk: flutter | |||
| myketpayment: | |||
| # When depending on this package from a real application you should use: | |||
| # myketpayment: ^x.y.z | |||
| # See https://dart.dev/tools/pub/dependencies#version-constraints | |||
| # The example app is bundled with the plugin so we use a path dependency on | |||
| # the parent directory to use the current plugin's version. | |||
| path: ../ | |||
| # The following adds the Cupertino Icons font to your application. | |||
| # Use with the CupertinoIcons class for iOS style icons. | |||
| cupertino_icons: ^0.1.3 | |||
| dev_dependencies: | |||
| flutter_test: | |||
| sdk: flutter | |||
| # For information on the generic Dart part of this file, see the | |||
| # following page: https://dart.dev/tools/pub/pubspec | |||
| # The following section is specific to Flutter. | |||
| flutter: | |||
| # The following line ensures that the Material Icons font is | |||
| # included with your application, so that you can use the icons in | |||
| # the material Icons class. | |||
| uses-material-design: true | |||
| # To add assets to your application, add an assets section, like this: | |||
| # assets: | |||
| # - images/a_dot_burr.jpeg | |||
| # - images/a_dot_ham.jpeg | |||
| # An image asset can refer to one or more resolution-specific "variants", see | |||
| # https://flutter.dev/assets-and-images/#resolution-aware. | |||
| # For details regarding adding assets from package dependencies, see | |||
| # https://flutter.dev/assets-and-images/#from-packages | |||
| # To add custom fonts to your application, add a fonts section here, | |||
| # in this "flutter" section. Each entry in this list should have a | |||
| # "family" key with the font family name, and a "fonts" key with a | |||
| # list giving the asset and other descriptors for the font. For | |||
| # example: | |||
| # fonts: | |||
| # - family: Schyler | |||
| # fonts: | |||
| # - asset: fonts/Schyler-Regular.ttf | |||
| # - asset: fonts/Schyler-Italic.ttf | |||
| # style: italic | |||
| # - family: Trajan Pro | |||
| # fonts: | |||
| # - asset: fonts/TrajanPro.ttf | |||
| # - asset: fonts/TrajanPro_Bold.ttf | |||
| # weight: 700 | |||
| # | |||
| # For details regarding fonts from package dependencies, | |||
| # see https://flutter.dev/custom-fonts/#from-packages | |||
| @@ -0,0 +1,27 @@ | |||
| // This is a basic Flutter widget test. | |||
| // | |||
| // To perform an interaction with a widget in your test, use the WidgetTester | |||
| // utility that Flutter provides. For example, you can send tap and scroll | |||
| // gestures. You can also use WidgetTester to find child widgets in the widget | |||
| // tree, read text, and verify that the values of widget properties are correct. | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_test/flutter_test.dart'; | |||
| import 'package:myketpayment_example/main.dart'; | |||
| void main() { | |||
| testWidgets('Verify Platform version', (WidgetTester tester) async { | |||
| // Build our app and trigger a frame. | |||
| await tester.pumpWidget(MyApp()); | |||
| // Verify that platform version is retrieved. | |||
| expect( | |||
| find.byWidgetPredicate( | |||
| (Widget widget) => widget is Text && | |||
| widget.data.startsWith('Running on:'), | |||
| ), | |||
| findsOneWidget, | |||
| ); | |||
| }); | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <meta content="IE=Edge" http-equiv="X-UA-Compatible"> | |||
| <meta name="description" content="Demonstrates how to use the myketpayment plugin."> | |||
| <!-- iOS meta tags & icons --> | |||
| <meta name="apple-mobile-web-app-capable" content="yes"> | |||
| <meta name="apple-mobile-web-app-status-bar-style" content="black"> | |||
| <meta name="apple-mobile-web-app-title" content="myketpayment_example"> | |||
| <link rel="apple-touch-icon" href="icons/Icon-192.png"> | |||
| <!-- Favicon --> | |||
| <link rel="shortcut icon" type="image/png" href="favicon.png"/> | |||
| <title>myketpayment_example</title> | |||
| <link rel="manifest" href="manifest.json"> | |||
| </head> | |||
| <body> | |||
| <!-- This script installs service_worker.js to provide PWA functionality to | |||
| application. For more information, see: | |||
| https://developers.google.com/web/fundamentals/primers/service-workers --> | |||
| <script> | |||
| if ('serviceWorker' in navigator) { | |||
| window.addEventListener('load', function () { | |||
| navigator.serviceWorker.register('flutter_service_worker.js'); | |||
| }); | |||
| } | |||
| </script> | |||
| <script src="main.dart.js" type="application/javascript"></script> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,23 @@ | |||
| { | |||
| "name": "myketpayment_example", | |||
| "short_name": "myketpayment_example", | |||
| "start_url": ".", | |||
| "display": "standalone", | |||
| "background_color": "#0175C2", | |||
| "theme_color": "#0175C2", | |||
| "description": "Demonstrates how to use the myketpayment plugin.", | |||
| "orientation": "portrait-primary", | |||
| "prefer_related_applications": false, | |||
| "icons": [ | |||
| { | |||
| "src": "icons/Icon-192.png", | |||
| "sizes": "192x192", | |||
| "type": "image/png" | |||
| }, | |||
| { | |||
| "src": "icons/Icon-512.png", | |||
| "sizes": "512x512", | |||
| "type": "image/png" | |||
| } | |||
| ] | |||
| } | |||
| @@ -0,0 +1,37 @@ | |||
| .idea/ | |||
| .vagrant/ | |||
| .sconsign.dblite | |||
| .svn/ | |||
| .DS_Store | |||
| *.swp | |||
| profile | |||
| DerivedData/ | |||
| build/ | |||
| GeneratedPluginRegistrant.h | |||
| GeneratedPluginRegistrant.m | |||
| .generated/ | |||
| *.pbxuser | |||
| *.mode1v3 | |||
| *.mode2v3 | |||
| *.perspectivev3 | |||
| !default.pbxuser | |||
| !default.mode1v3 | |||
| !default.mode2v3 | |||
| !default.perspectivev3 | |||
| xcuserdata | |||
| *.moved-aside | |||
| *.pyc | |||
| *sync/ | |||
| Icon? | |||
| .tags* | |||
| /Flutter/Generated.xcconfig | |||
| /Flutter/flutter_export_environment.sh | |||
| @@ -0,0 +1,4 @@ | |||
| #import <Flutter/Flutter.h> | |||
| @interface MyketpaymentPlugin : NSObject<FlutterPlugin> | |||
| @end | |||
| @@ -0,0 +1,20 @@ | |||
| #import "MyketpaymentPlugin.h" | |||
| @implementation MyketpaymentPlugin | |||
| + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { | |||
| FlutterMethodChannel* channel = [FlutterMethodChannel | |||
| methodChannelWithName:@"myketpayment" | |||
| binaryMessenger:[registrar messenger]]; | |||
| MyketpaymentPlugin* instance = [[MyketpaymentPlugin alloc] init]; | |||
| [registrar addMethodCallDelegate:instance channel:channel]; | |||
| } | |||
| - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { | |||
| if ([@"getPlatformVersion" isEqualToString:call.method]) { | |||
| result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); | |||
| } else { | |||
| result(FlutterMethodNotImplemented); | |||
| } | |||
| } | |||
| @end | |||
| @@ -0,0 +1,23 @@ | |||
| # | |||
| # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. | |||
| # Run `pod lib lint myketpayment.podspec' to validate before publishing. | |||
| # | |||
| Pod::Spec.new do |s| | |||
| s.name = 'myketpayment' | |||
| s.version = '0.0.1' | |||
| s.summary = 'Add myket in app purchase' | |||
| s.description = <<-DESC | |||
| Add myket in app purchase | |||
| DESC | |||
| s.homepage = 'http://example.com' | |||
| s.license = { :file => '../LICENSE' } | |||
| s.author = { 'Your Company' => 'email@example.com' } | |||
| s.source = { :path => '.' } | |||
| s.source_files = 'Classes/**/*' | |||
| s.public_header_files = 'Classes/**/*.h' | |||
| s.dependency 'Flutter' | |||
| s.platform = :ios, '8.0' | |||
| # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. | |||
| s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } | |||
| end | |||
| @@ -0,0 +1,21 @@ | |||
| import 'dart:async'; | |||
| import 'dart:convert'; | |||
| import 'package:flutter/services.dart'; | |||
| class Myketpayment { | |||
| static const MethodChannel _channel = const MethodChannel('myketpayment'); | |||
| static Future<bool> setup(String rsa) async { | |||
| final bool version = await _channel.invokeMethod('setup', {"rsa": rsa}); | |||
| return version; | |||
| } | |||
| static Future<Map> buy({String sku, bool consume = false, String payload = ""}) async { | |||
| Map result = await _channel.invokeMethod('buy', {"sku": sku, "payload": payload, "consume": consume}); | |||
| return result; | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <module type="JAVA_MODULE" version="4"> | |||
| <component name="NewModuleRootManager" inherit-compiler-output="true"> | |||
| <exclude-output /> | |||
| <content url="file://$MODULE_DIR$"> | |||
| <sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/.dart_tool" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/.idea" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/.pub" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/build" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/example/.pub" /> | |||
| <excludeFolder url="file://$MODULE_DIR$/example/build" /> | |||
| </content> | |||
| <orderEntry type="sourceFolder" forTests="false" /> | |||
| <orderEntry type="library" name="Dart SDK" level="project" /> | |||
| <orderEntry type="library" name="Flutter Plugins" level="project" /> | |||
| </component> | |||
| </module> | |||
| @@ -0,0 +1,140 @@ | |||
| # Generated by pub | |||
| # See https://dart.dev/tools/pub/glossary#lockfile | |||
| packages: | |||
| async: | |||
| dependency: transitive | |||
| description: | |||
| name: async | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.4.1" | |||
| boolean_selector: | |||
| dependency: transitive | |||
| description: | |||
| name: boolean_selector | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.0" | |||
| charcode: | |||
| dependency: transitive | |||
| description: | |||
| name: charcode | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.3" | |||
| clock: | |||
| dependency: transitive | |||
| description: | |||
| name: clock | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.1" | |||
| collection: | |||
| dependency: transitive | |||
| description: | |||
| name: collection | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.14.12" | |||
| fake_async: | |||
| dependency: transitive | |||
| description: | |||
| name: fake_async | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.0" | |||
| flutter: | |||
| dependency: "direct main" | |||
| description: flutter | |||
| source: sdk | |||
| version: "0.0.0" | |||
| flutter_test: | |||
| dependency: "direct dev" | |||
| description: flutter | |||
| source: sdk | |||
| version: "0.0.0" | |||
| matcher: | |||
| dependency: transitive | |||
| description: | |||
| name: matcher | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.12.6" | |||
| meta: | |||
| dependency: transitive | |||
| description: | |||
| name: meta | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.8" | |||
| path: | |||
| dependency: transitive | |||
| description: | |||
| name: path | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.7.0" | |||
| sky_engine: | |||
| dependency: transitive | |||
| description: flutter | |||
| source: sdk | |||
| version: "0.0.99" | |||
| source_span: | |||
| dependency: transitive | |||
| description: | |||
| name: source_span | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.7.0" | |||
| stack_trace: | |||
| dependency: transitive | |||
| description: | |||
| name: stack_trace | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.9.3" | |||
| stream_channel: | |||
| dependency: transitive | |||
| description: | |||
| name: stream_channel | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.0" | |||
| string_scanner: | |||
| dependency: transitive | |||
| description: | |||
| name: string_scanner | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.5" | |||
| term_glyph: | |||
| dependency: transitive | |||
| description: | |||
| name: term_glyph | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.0" | |||
| test_api: | |||
| dependency: transitive | |||
| description: | |||
| name: test_api | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.2.15" | |||
| typed_data: | |||
| dependency: transitive | |||
| description: | |||
| name: typed_data | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.6" | |||
| vector_math: | |||
| dependency: transitive | |||
| description: | |||
| name: vector_math | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.8" | |||
| sdks: | |||
| dart: ">=2.7.0 <3.0.0" | |||
| flutter: ">=1.10.0" | |||
| @@ -0,0 +1,65 @@ | |||
| name: myketpayment | |||
| description: Add myket in app purchase | |||
| version: 0.0.1 | |||
| author: | |||
| homepage: | |||
| environment: | |||
| sdk: ">=2.7.0 <3.0.0" | |||
| flutter: ">=1.10.0" | |||
| dependencies: | |||
| flutter: | |||
| sdk: flutter | |||
| dev_dependencies: | |||
| flutter_test: | |||
| sdk: flutter | |||
| # For information on the generic Dart part of this file, see the | |||
| # following page: https://dart.dev/tools/pub/pubspec | |||
| # The following section is specific to Flutter. | |||
| flutter: | |||
| # This section identifies this Flutter project as a plugin project. | |||
| # The 'pluginClass' and Android 'package' identifiers should not ordinarily | |||
| # be modified. They are used by the tooling to maintain consistency when | |||
| # adding or updating assets for this project. | |||
| plugin: | |||
| platforms: | |||
| android: | |||
| package: ir.appeto.myketpayment | |||
| pluginClass: MyketpaymentPlugin | |||
| ios: | |||
| pluginClass: MyketpaymentPlugin | |||
| # To add assets to your plugin package, add an assets section, like this: | |||
| # assets: | |||
| # - images/a_dot_burr.jpeg | |||
| # - images/a_dot_ham.jpeg | |||
| # | |||
| # For details regarding assets in packages, see | |||
| # https://flutter.dev/assets-and-images/#from-packages | |||
| # | |||
| # An image asset can refer to one or more resolution-specific "variants", see | |||
| # https://flutter.dev/assets-and-images/#resolution-aware. | |||
| # To add custom fonts to your plugin package, add a fonts section here, | |||
| # in this "flutter" section. Each entry in this list should have a | |||
| # "family" key with the font family name, and a "fonts" key with a | |||
| # list giving the asset and other descriptors for the font. For | |||
| # example: | |||
| # fonts: | |||
| # - family: Schyler | |||
| # fonts: | |||
| # - asset: fonts/Schyler-Regular.ttf | |||
| # - asset: fonts/Schyler-Italic.ttf | |||
| # style: italic | |||
| # - family: Trajan Pro | |||
| # fonts: | |||
| # - asset: fonts/TrajanPro.ttf | |||
| # - asset: fonts/TrajanPro_Bold.ttf | |||
| # weight: 700 | |||
| # | |||
| # For details regarding fonts in packages, see | |||
| # https://flutter.dev/custom-fonts/#from-packages | |||
| @@ -0,0 +1,23 @@ | |||
| import 'package:flutter/services.dart'; | |||
| import 'package:flutter_test/flutter_test.dart'; | |||
| import 'package:myketpayment/myketpayment.dart'; | |||
| void main() { | |||
| const MethodChannel channel = MethodChannel('myketpayment'); | |||
| TestWidgetsFlutterBinding.ensureInitialized(); | |||
| setUp(() { | |||
| channel.setMockMethodCallHandler((MethodCall methodCall) async { | |||
| return '42'; | |||
| }); | |||
| }); | |||
| tearDown(() { | |||
| channel.setMockMethodCallHandler(null); | |||
| }); | |||
| test('getPlatformVersion', () async { | |||
| expect(await Myketpayment.platformVersion, '42'); | |||
| }); | |||
| } | |||