PayPal Android Step 1: Layout, Initialization, and Handling Server Response


Example

The complete sample code for this application (Android + Node server) is available in the PayPal Developer Github repository.

The first stage of creating the Android portion of our application is to set up a basic layout and handle responses that come back from the server that we'll set up in Node.

Start by creating a new PayPalConfiguration object to house your application information.

private static PayPalConfiguration config = new PayPalConfiguration()
        .environment(PayPalConfiguration.ENVIRONMENT_SANDBOX)
        .clientId("YOUR APPLICATION CLIENT ID")
        .merchantName("My Store")
        .merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy"))
        .merchantUserAgreementUri(Uri.parse("https://www.example.com/legal"));

Next, we add a simple button to onCreate(...) to act as our payment initiation. This is simply to trigger off the action, and should be placed as the initiation process for creating a future payment for a user (e.g. when they agree upon a subscription).

@Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Button button = (Button) findViewById(R.id.paypal_button);
}

Under res > layout > activity_main.xml we add the definition for the button with its associated action, when clicked it calls beginFuturePayment(...), which we'll define in a minute.

<Button android:id="@+id/paypal_button"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="@string/paypal_button"
    android:onClick="beginFuturePayment" />

Under res > values > strings.xml we then add a string reference for the button.

<string name="paypal_button">Process Future Payment</string>

Now we add the button handler, to initiate the call to begin the future payment process when the user clicks the button. What we are doing here is starting the payment service with the configuration object we set up at the top of this example.

public void beginFuturePayment(View view){
    Intent serviceConfig = new Intent(this, PayPalService.class);
    serviceConfig.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
    startService(serviceConfig);

    Intent intent = new Intent(this, PayPalFuturePaymentActivity.class);
    intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
    startActivityForResult(intent, 0);
}

When that call to make a future payment is initiated, we will be given some information that will need to be sent to our server. We extract this information from the valid future payment request (authCode and metadataId), then make execute the async request to the server to complete the future payment (detailed in step 2).

@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data){
    if (resultCode == Activity.RESULT_OK){
        PayPalAuthorization auth = data.getParcelableExtra(PayPalFuturePaymentActivity.EXTRA_RESULT_AUTHORIZATION);
        if (auth != null){
            try{
                //prepare params to be sent to server
                String authCode = auth.getAuthorizationCode();
                String metadataId = PayPalConfiguration.getClientMetadataId(this);
                String [] params = {authCode, metadataId};

                //process async server request for token + payment
                ServerRequest req = new ServerRequest();
                req.execute(params);

            } catch (JSONException e) {
                Log.e("FPSample", "JSON Exception: ", e);
            }
        }
    } else if (resultCode == Activity.RESULT_CANCELED) {
        Log.i("FPSample", "User canceled.");
    } else if (resultCode == PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
        Log.i("FPSample", "Invalid configuration");
    }
}

Lastly, we define our onDestroy().

@Override
public void onDestroy(){
    stopService(new Intent(this, PayPalService.class));
    super.onDestroy();
}