Skip to content

Instantly share code, notes, and snippets.

@srinidhiprabandham
Created December 13, 2017 08:11
Show Gist options
  • Select an option

  • Save srinidhiprabandham/cdd86f59ef9284015f6d00c7d4b6e085 to your computer and use it in GitHub Desktop.

Select an option

Save srinidhiprabandham/cdd86f59ef9284015f6d00c7d4b6e085 to your computer and use it in GitHub Desktop.
package com.games_plaza;
import com.globalcharge.android.PaymentListener;
import com.globalcharge.android.BillingManager;
import com.globalcharge.android.products.Product;
import com.globalcharge.android.Environment;
import com.globalcharge.android.AbTestScreenType;
import android.support.v7.app.AppCompatActivity;
import android.content.pm.PackageManager;
import android.widget.Toast;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.ReactActivity;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Random;
import java.lang.System;
public class PaymentModule extends ReactContextBaseJavaModule {
public Product selectedProduct;
public MobilePaymentActivity mpa;
// This method is required by Reactnative.
public PaymentModule(ReactApplicationContext reactContext) {
super(reactContext);
}
// This method is required by Reactnative.
@Override
public String getName() {
return "PaymentModule";
}
// MobilePaymentActivity is implemented as a new class as we cannot have multiple subclassing in jave
// and the parent class has to be a subclass of ReactContextBaseJavaModule
// We also implement all methods of the PaymentListener (class in the sdk) as this is where we want to
// keep things in one place.
// The parent class will only be a bridge between react native and this class. And will instantiate a
// new instance of MobilePaymentActivity and call necessry methods.
private class MobilePaymentActivity extends AppCompatActivity implements PaymentListener {
//The handler is essential for the callbacks to the UI thread.by the BillingManager class.
public Handler mHandler = new Handler();
public BillingManager billingManager = new BillingManager(getReactApplicationContext(), mHandler);
private String message;
// private BillingManager billingManager;
private long selectedAccount;
private String endUserId, clientAppVersion;
// ToastRunnable is needed as the callback that we get when we initiate the payment with
// biilingManger.beginPayment is asynchronous and one that call is done. The focus will be shifted
// back to the worker thread that is the instance of this class.
// But since we need some way to notify the UI process / Thread that we received the products
// we create a Toast here and in the onProducsReceived we just set the message and pass the message
// to the handler so that it can interact with the background and UI threads.
Runnable onSubscriptionCallback = new Runnable() {
public void run() {
Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
};
Runnable manualPurchaseRunnable = new Runnable() {
public void run() {
Log.d("ManualPurchaseRunnable", "This got called !!!");
billingManager.purchaseProduct(selectedProduct);
}
};
// Due to implementing the PaymentListener we have to define this method.
public void onFailure(String message) {
Log.d("onFailure", "This is a failure call from sdk backend");
this.message = "Things blew away - " + message;
mHandler.post(onSubscriptionCallback);
}
// Due to implementing the PaymentListener we have to define this method.
public void onProductsReceived(List<Product> products) {
// Loop through the list of products that we get and checck if we have those
// defined in our mapping table. TODO
List<String> allowedProducts = Arrays.asList("277", "279", "300");
Product product = products.get(0);
selectedProduct = product;
Log.d("onProductsReceived", "Call came to on Products received !!");
if(allowedProducts.contains(Long.toString(product.getProductId()))) {
// NOTE for now we will send the entire details in a formated way to the UI.
// but when we get actual details with multiple products we have to decide which product we will
// show the user. May be in a new method or service class (ShowProductDetailsService)
String productDetails;
productDetails = Long.toString(product.getProductId()) + ";" + product.getInitialPricePoint() + " " + product.getCurrency() + " per week.";
notifyReactUI("onProductsReceived", productDetails);
} else {
// this.message = "It is not equal !! Some products are missing on our end -" + allowedProducts.get(0) + " " + product.getProductId();
// TODO handle this error and show a page that says we could not get any products
// may be by sending a failure event
}
}
// Due to implementing the PaymentListener we have to define this method.
public void onProductSelected(Product product) {
}
// Due to implementing the PaymentListener we have to define this method.
public void onCancelled() {
}
// Due to implementing the PaymentListener we have to define this method.
public void onSuccess(int statusCode) {
Log.d("onSuccess", "This is a success call from sdk backend");
this.message = "Payment has been successful...." + statusCode;
mHandler.post(onSubscriptionCallback);
}
// Due to implementing the PaymentListener we have to define this method.
public void onPaymentStateChanged(String state) {
}
// Due to implementing the PaymentListener we have to define this method.
public void onSubscriptionCancelSuccess(String a, String b, String c) {
}
// Due to implementing the PaymentListener we have to define this method.
public void onSubscriptionCancelFailure(String a, String b, String c) {
}
public void startProductPurchase() {
mHandler.post(manualPurchaseRunnable);
}
// THis is a custom method which will be called from the parent class
// when ever a user clicks on a "Premium product" or clicks on subscribe.
// This method is also responsible to intiate a subscription process with the
// global charge API
public void requestSubscription() {
boolean isOneStepBilling = false;
//TODO remove this line when going to production.
billingManager.setAbTestScreenType(AbTestScreenType.ORIGINAL_SCREENS);
billingManager.setTestUrl("http://inappdev.globalcharge.com:8040/inappservices_silent/rest");
billingManager.setEnvironment(Environment.PRODUCTION);
billingManager.registerPaymentListener(this);
try {
// Toast.makeText(getReactApplicationContext(), "Your Selection is registered. Please wait...", Toast.LENGTH_LONG).show();
//TODO change this to our details
selectedAccount = 9444999;
endUserId = "testUser1";
clientAppVersion = "0.0.1";
} catch (Exception e) {
// TODO Auto-generated catch block
}
// billingManager.registerPaymentListener(getReactApplicationContext());
/****************************** START IMSI FAKING ****************************************/
// This is code allows you to fake the handset so that it thinks there is a UK SIM in it, and will load UK products from our server,
// this next 3 lines should be removed or disabled before generating the production app
billingManager.setFakeTestMcc("234");
billingManager.setFakeTestMnc("30");
billingManager.setFakeTestImsi("234300902691112");
boolean isPaymentBegan = billingManager.beginPayment(
selectedAccount, endUserId, clientAppVersion,
isOneStepBilling);
if(isPaymentBegan) {
// This is needed for testing puroses only
// Toast.makeText(getReactApplicationContext(), "Payment began true", Toast.LENGTH_LONG).show();
} else {
// TODO may be redirect the user back to the all products page and tell them that the subscription failed
// we could not initiate the payment process with GlobalCharge ??
Toast.makeText(getReactApplicationContext(), "Payment began false", Toast.LENGTH_LONG).show();
}
}
}
// This will be called when the user clicks on "Subscribe" from ReactNative side
@ReactMethod
public void onSubscribeClicked() {
mpa = new MobilePaymentActivity();
mpa.requestSubscription();
}
@ReactMethod
public void onSubscriptionConfirmation() {
mpa.startProductPurchase();
}
// This is only a convience method so that it is easy to call and dispatch some event to the UI
// without having to deal with knowing the internals of how the event will be sent.
public void notifyReactUI(String eventName,String value){
WritableMap params = Arguments.createMap();
params.putString("event_data", value);
sendEvent(getReactApplicationContext(), eventName, params);
}
private void sendEvent(ReactContext reactContext,String eventName, WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment