droidcon paris: the new android sdk

Post on 15-May-2015

1.330 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

This speech was held by Tim Messerschmidt at Droidcon Paris 2013.

TRANSCRIPT

PayPal’s New Android SDK: Kicking Ass With Payments

Tim Messerschmidt Droidcon Paris 2013

This talk will be about

-  What is PayPal? -  Log In with PayPal -  PayPal Android SDK

Who Am I?

Tim Messerschmidt, Developer Evangelist working for PayPal. Android Developer living in Berlin. I ♥ Java, Ruby, CSS3, HTML5 & JavaScript!

What is PayPal?

Enable merchants to

sell online

What is PayPal?

Enable customers to

buy online

What is PayPal?

Payment Scenario

Sender Receiver

Transaction

eCommerce

Sender Receiver

Transaction

Item / Service

Secure Easy Fast

Requirements

128m

active users

What is PayPal?

193

countries & regions

What is PayPal?

25

supported currencies

What is PayPal?

80

localized websites

What is PayPal?

France

fully supported

What is PayPal?

Local Merchants

Big Mac Menu:

-  Fries -  Ketchup -  Water ... !""#$%& $' (")*'(+

Painless Payments for Droids Tim Messerschmidt

Identity

Login with...

Google Facebook Twitter

... or PayPal.

Login with...

Name Email

Date of Birth

Locale Time Zone

Address

Gender

Language

Phone Number

Verified Account

Creation Date

Your Identity

Log In via PayPal in the browser or a WebView.

Log In with PayPal

Authorization & Authentication

Log In with PayPal

OAuth 2.0 & OpenID Connect

No need to (re-)enter your password after

logging in

Seamless Checkout

Painless Payments for Droids Tim Messerschmidt

Summarizing Identity

Painless Payments for Droids Tim Messerschmidt

Money

Lots Of Money

Painless Payments for Droids Tim Messerschmidt

Digital Goods

Physical Goods

Physical Goods

2 ways

Backend or via SDK

Using PayPal

Android SDK

Sample App:

•  Sell a football jersey •  Fast Checkout •  Nice Interface

Present the product & allow to purchase it

Android SDK

Allow to pay via PayPal or Card

Android SDK

The user enters his credentials:

•  Email •  Password

Android SDK

The user needs to confirm his payment...

Android SDK

... and will be presented a confirmation of his purchase afterwards.

Android SDK

That’s nice... BUT:

What if the user doesn’t want to use PayPal or doesn’t have an account?

Accept credit cards in your application manually or...

Android SDK

... via image recognition technology in your app!

Android SDK

Implementation

In 10 minutes

How-to

<!-- Hardware features --> <uses-feature

android:name="android.hardware.camera” android:required="false" />

<uses-feature android:name="android.hardware.camera.autofocus” android:required="false" />

<!–- Permissions --> <uses-permission

android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission

android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission

android:name="android.permission.INTERNET" /> <!-- card.io scanning --> <uses-permission

android:name="android.permission.CAMERA" /> <uses-permission

android:name="android.permission.VIBRATE" />

How-to

AndroidManifest.xml:

<!-- Hardware features --> <uses-feature

android:name="android.hardware.camera” android:required="false" />

<uses-feature android:name="android.hardware.camera.autofocus” android:required="false" />

<!–- Permissions --> <uses-permission

android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission

android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission

android:name="android.permission.INTERNET" /> <!-- card.io scanning --> <uses-permission

android:name="android.permission.CAMERA" /> <uses-permission

android:name="android.permission.VIBRATE" />

How-to

AndroidManifest.xml:

<!-- Hardware features --> <uses-feature

android:name="android.hardware.camera” android:required="false" />

<uses-feature android:name="android.hardware.camera.autofocus” android:required="false" />

<!–- Permissions --> <uses-permission

android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission

android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission

android:name="android.permission.INTERNET" /> <!-- card.io scanning --> <uses-permission

android:name="android.permission.CAMERA" /> <uses-permission

android:name="android.permission.VIBRATE" />

How-to

AndroidManifest.xml:

<!-- Hardware features --> <uses-feature

android:name="android.hardware.camera” android:required="false" />

<uses-feature android:name="android.hardware.camera.autofocus” android:required="false" />

<!–- Permissions --> <uses-permission

android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission

android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission

android:name="android.permission.INTERNET" /> <!-- card.io scanning --> <uses-permission

android:name="android.permission.CAMERA" /> <uses-permission

android:name="android.permission.VIBRATE" />

How-to

AndroidManifest.xml:

<service android:name="com.paypal.android.sdk.payments.PayPalService" android:exported="false"/> <activity android:name="com.paypal.android.sdk.payments.PaymentActivity"/> <activity android:name="com.paypal.android.sdk.payments.LoginActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentMethodActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentConfirmActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentCompletedActivity"/> <activity android:name="io.card.payment.CardIOActivity" android:configChanges="keyboardHidden|orientation"/> <activity android:name="io.card.payment.DataEntryActivity"/>

How-to

AndroidManifest.xml:

<service android:name="com.paypal.android.sdk.payments.PayPalService" android:exported="false"/> <activity android:name="com.paypal.android.sdk.payments.PaymentActivity"/> <activity android:name="com.paypal.android.sdk.payments.LoginActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentMethodActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentConfirmActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentCompletedActivity"/> <activity android:name="io.card.payment.CardIOActivity" android:configChanges="keyboardHidden|orientation"/> <activity android:name="io.card.payment.DataEntryActivity"/>

How-to

AndroidManifest.xml:

<service android:name="com.paypal.android.sdk.payments.PayPalService" android:exported="false"/> <activity android:name="com.paypal.android.sdk.payments.PaymentActivity"/> <activity android:name="com.paypal.android.sdk.payments.LoginActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentMethodActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentConfirmActivity"/> <activity android:name="com.paypal.android.sdk.payments.PaymentCompletedActivity"/> <activity android:name="io.card.payment.CardIOActivity" android:configChanges="keyboardHidden|orientation"/> <activity android:name="io.card.payment.DataEntryActivity"/>

How-to

AndroidManifest.xml:

// Can be NO_NETWORK for OFFLINE, SANDBOX for TESTING and LIVE for PRODUCTION private static final String CONFIG_ENVIRONMENT =

PaymentActivity.ENVIRONMENT_NO_NETWORK; // note that these credentials will differ between live & sandbox environments. private static final String CONFIG_CLIENT_ID =

"credential from developer.paypal.com"; // when testing in sandbox, this is likely the -facilitator email address. private static final String CONFIG_RECEIVER_EMAIL =

"your@email.com";

How-to

Your Activity: Define your credentials and Environment first.

// Can be NO_NETWORK for OFFLINE, SANDBOX for TESTING and LIVE for PRODUCTION private static final String CONFIG_ENVIRONMENT =

PaymentActivity.ENVIRONMENT_NO_NETWORK; // note that these credentials will differ between live & sandbox environments. private static final String CONFIG_CLIENT_ID =

"credential from developer.paypal.com"; // when testing in sandbox, this is likely the -facilitator email address. private static final String CONFIG_RECEIVER_EMAIL =

"your@email.com";

How-to

Your Activity: Define your credentials and Environment first.

// Can be NO_NETWORK for OFFLINE, SANDBOX for TESTING and LIVE for PRODUCTION private static final String CONFIG_ENVIRONMENT =

PaymentActivity.ENVIRONMENT_NO_NETWORK; // note that these credentials will differ between live & sandbox environments. private static final String CONFIG_CLIENT_ID =

"credential from developer.paypal.com"; // when testing in sandbox, this is likely the -facilitator email address. private static final String CONFIG_RECEIVER_EMAIL =

"your@email.com";

How-to

Your Activity: Define your credentials and Environment first.

// Can be NO_NETWORK for OFFLINE, SANDBOX for TESTING and LIVE for PRODUCTION private static final String CONFIG_ENVIRONMENT =

PaymentActivity.ENVIRONMENT_NO_NETWORK; // note that these credentials will differ between live & sandbox environments. private static final String CONFIG_CLIENT_ID =

"credential from developer.paypal.com"; // when testing in sandbox, this is likely the -facilitator email address. private static final String CONFIG_RECEIVER_EMAIL =

"your@email.com";

How-to

Your Activity: Define your credentials and Environment first.

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

// your code here Intent intent = new Intent(this, PayPalService.class); intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startService(intent); }

How-to

Your Activity: Start the PayPal-Service in your onCreate( ) method

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

// your code here Intent intent = new Intent(this, PayPalService.class); intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startService(intent); }

How-to

Your Activity: Start the PayPal-Service in your onCreate( ) method

PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(“59.99"), "USD", "Paris SG Jersey");

Intent intent = new Intent(this, PaymentActivity.class); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); intent.putExtra(PaymentActivity.EXTRA_PAYER_ID, "myPayer"); // Repeat passing the credentials intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startActivityForResult(intent, PAYMENT_REQUEST);

How-to

Your Activity: Start the payment itself via a button or something similar

PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(“59.99"), "USD", "Paris SG Jersey");

Intent intent = new Intent(this, PaymentActivity.class); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); intent.putExtra(PaymentActivity.EXTRA_PAYER_ID, "myPayer"); // Repeat passing the credentials intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startActivityForResult(intent, PAYMENT_REQUEST);

How-to

Your Activity: Start the payment itself via a button or something similar

PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(“59.99"), "USD", "Paris SG Jersey");

Intent intent = new Intent(this, PaymentActivity.class); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); intent.putExtra(PaymentActivity.EXTRA_PAYER_ID, "myPayer"); // Repeat passing the credentials intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startActivityForResult(intent, PAYMENT_REQUEST);

How-to

Your Activity: Start the payment itself via a button or something similar

PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(“59.99"), "USD", "Paris SG Jersey");

Intent intent = new Intent(this, PaymentActivity.class); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); intent.putExtra(PaymentActivity.EXTRA_PAYER_ID, "myPayer"); // Repeat passing the credentials intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startActivityForResult(intent, PAYMENT_REQUEST);

How-to

Your Activity: Start the payment itself via a button or something similar

PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(“59.99"), "USD", "Paris SG Jersey");

Intent intent = new Intent(this, PaymentActivity.class); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); intent.putExtra(PaymentActivity.EXTRA_PAYER_ID, "myPayer"); // Repeat passing the credentials intent.putExtra(PaymentActivity.EXTRA_PAYPAL_ENVIRONMENT, CONFIG_ENVIRONMENT); intent.putExtra(PaymentActivity.EXTRA_CLIENT_ID, CONFIG_CLIENT_ID); intent.putExtra(PaymentActivity.EXTRA_RECEIVER_EMAIL, CONFIG_RECEIVER_EMAIL); startActivityForResult(intent, PAYMENT_REQUEST);

How-to

Your Activity: Start the payment itself via a button or something similar

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { PaymentConfirmation confirm =

data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION); if (confirm != null) {

verifyPayment(confirm); }

} else if (resultCode == Activity.RESULT_CANCELED) { // Show the user that this got canceled } else if (resultCode == PaymentActivity.RESULT_PAYMENT_INVALID) { // Check the docs ;) } }

How-to

Your Activity: Check the result after the user used PayPal

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { PaymentConfirmation confirm =

data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION); if (confirm != null) {

verifyPayment(confirm); }

} else if (resultCode == Activity.RESULT_CANCELED) { // Show the user that this got canceled } else if (resultCode == PaymentActivity.RESULT_PAYMENT_INVALID) { // Check the docs ;) } }

How-to

Your Activity: Check the result after the user used PayPal

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { PaymentConfirmation confirm =

data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION); if (confirm != null) {

verifyPayment(confirm); }

} else if (resultCode == Activity.RESULT_CANCELED) { // Show the user that this got canceled } else if (resultCode == PaymentActivity.RESULT_PAYMENT_INVALID) { // Check the docs ;) } }

How-to

Your Activity: Check the result after the user used PayPal

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { PaymentConfirmation confirm =

data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION); if (confirm != null) {

verifyPayment(confirm); }

} else if (resultCode == Activity.RESULT_CANCELED) { // Show the user that this got canceled } else if (resultCode == PaymentActivity.RESULT_PAYMENT_INVALID) { // Check the docs ;) } }

How-to

Your Activity: Check the result after the user used PayPal

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

How-to

Your Activity: Stop your service in the lifecycle’s onDestroy( ) method to make sure it ends nicely and doesn’t use unneeded resources.

Your app needs to communicate with a server to verify

payments

Verifying Payments

Criteria to use to verify payments:

bit.ly/19FIis6

Verifying Payments

{ "proof_of_payment": { "rest_api": { "state": "approved", "payment_id": "API-PAYMENT-ID-1843" } }, "payment": { "short_description": "Paris SG Jersey", "amount": ”59.99", "currency_code": "USD" }, "client": { "platform": "Android", "paypal_sdk_version": "1.0.2", "environment": "live", "product_name": "PayPal Android SDK" } }

Verifying Payments

REST-API proof of payment: Adaptive Payments proof of payment: { "proof_of_payment": { "adaptive_payment": { "pay_key": "AP-70M68096ML426802W", "payment_exec_status": "COMPLETED", "timestamp": "2013-02-20T00:26:25Z", "app_id": "APP-91B933855X481767M" } }, "payment": { "short_description": "Paris SG Shirt", "amount": "59.99", "currency_code": "USD" }, "client": { "platform": "Android", "paypal_sdk_version": "1.0.2", "environment": "live", "product_name": "PayPal Android SDK" } }

{ "proof_of_payment": { "rest_api": { "state": "approved", "payment_id": "API-PAYMENT-ID-1843" } }, "payment": { "short_description": "Paris SG Jersey", "amount": ”59.99", "currency_code": "USD" }, "client": { "platform": "Android", "paypal_sdk_version": "1.0.2", "environment": "live", "product_name": "PayPal Android SDK" } }

Verifying Payments

REST-API proof of payment: Adaptive Payments proof of payment: { "proof_of_payment": { "adaptive_payment": { "pay_key": "AP-70M68096ML426802W", "payment_exec_status": "COMPLETED", "timestamp": "2013-02-20T00:26:25Z", "app_id": "APP-91B933855X481767M" } }, "payment": { "short_description": "Paris SG Shirt", "amount": "59.99", "currency_code": "USD" }, "client": { "platform": "Android", "paypal_sdk_version": "1.0.2", "environment": "live", "product_name": "PayPal Android SDK" } }

Somebody did that work for you:

bit.ly/19FHQde

Verifying Payments

Android Studio

Gradle doesn’t support bundling .so files with your apk yet

US only

Europe coming soon!

Important

Documentation

developer.paypal.com

Information

Open Source

GitHub.com/paypal

Information

Questions?

Thanks! Tim Messerschmidt

@SeraAndroid tmesserschmidt@paypal.com

SlideShare.com/paypal

top related