Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

Commit

Permalink
Release 2.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjacunski committed Aug 22, 2014
1 parent 4977498 commit e20293f
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ Later, when that customer initiates a payment:
1. [Obtain an Application Correlation ID](docs/future_payments_mobile.md#obtain-an-application-correlation-id) that you'll pass to your server.
2. On your server, [Create a Payment](docs/future_payments_server.md#create-a-payment) using your OAuth2 tokens, the Application Correlation ID, and PayPal's API.

### Profile Sharing

Your customer logs in to PayPal and consents to PayPal sharing information with you:

1. [Obtain Customer Consent](docs/profile_sharing_mobile.md#obtain-customer-consent) to receive an authorization code.
2. On your server, use this authorization code to [Obtain OAuth2 Tokens](docs/profile_sharing_server.md#obtain-oauth2-tokens).
3. On your server, [Retrieve Customer Information](docs/profile_sharing_server.md#retrieve-customer-information) using your OAuth2 tokens and PayPal's API.


## Integration with the PayPal Wallet App

Expand Down
3 changes: 3 additions & 0 deletions SampleApp/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
<activity android:name="com.paypal.android.sdk.payments.PayPalFuturePaymentActivity" />
<activity android:name="com.paypal.android.sdk.payments.FuturePaymentConsentActivity" />
<activity android:name="com.paypal.android.sdk.payments.FuturePaymentInfoActivity" />
<activity android:name="com.paypal.android.sdk.payments.PayPalProfileSharingActivity" />
<activity android:name="com.paypal.android.sdk.payments.ProfileSharingConsentActivity" />

<activity
android:name="io.card.payment.CardIOActivity"
android:configChanges="keyboardHidden|orientation" />
Expand Down
Binary file removed SampleApp/libs/PayPalAndroidSDK-2.3.5.jar
Binary file not shown.
Binary file added SampleApp/libs/PayPalAndroidSDK-2.4.0.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.paypal.android.sdk.payments.PayPalConfiguration;
import com.paypal.android.sdk.payments.PayPalFuturePaymentActivity;
import com.paypal.android.sdk.payments.PayPalItem;
import com.paypal.android.sdk.payments.PayPalOAuthScopes;
import com.paypal.android.sdk.payments.PayPalPayment;
import com.paypal.android.sdk.payments.PayPalPaymentDetails;
import com.paypal.android.sdk.payments.PayPalProfileSharingActivity;
import com.paypal.android.sdk.payments.PayPalService;
import com.paypal.android.sdk.payments.PaymentActivity;
import com.paypal.android.sdk.payments.PaymentConfirmation;
Expand All @@ -23,6 +25,10 @@

import java.math.BigDecimal;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
* Basic sample using the SDK to make a payment or consent to future payments.
*
Expand All @@ -47,6 +53,7 @@ public class SampleActivity extends Activity {

private static final int REQUEST_CODE_PAYMENT = 1;
private static final int REQUEST_CODE_FUTURE_PAYMENT = 2;
private static final int REQUEST_CODE_PROFILE_SHARING = 3;

private static PayPalConfiguration config = new PayPalConfiguration()
.environment(CONFIG_ENVIRONMENT)
Expand Down Expand Up @@ -133,6 +140,22 @@ public void onFuturePaymentPressed(View pressed) {
startActivityForResult(intent, REQUEST_CODE_FUTURE_PAYMENT);
}

public void onProfileSharingPressed(View pressed) {
Intent intent = new Intent(SampleActivity.this, PayPalProfileSharingActivity.class);
intent.putExtra(PayPalProfileSharingActivity.EXTRA_REQUESTED_SCOPES, getOauthScopes());
startActivityForResult(intent, REQUEST_CODE_PROFILE_SHARING);
}

private PayPalOAuthScopes getOauthScopes() {
/* create the set of required scopes
* Note: see https://developer.paypal.com/docs/integration/direct/identity/attributes/ for mapping between the
* attributes you select for this app in the PayPal developer portal and the scopes required here.
*/
Set<String> scopes = new HashSet<String>(
Arrays.asList(PayPalOAuthScopes.PAYPAL_SCOPE_EMAIL, PayPalOAuthScopes.PAYPAL_SCOPE_ADDRESS) );
return new PayPalOAuthScopes(scopes);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_PAYMENT) {
Expand Down Expand Up @@ -195,6 +218,34 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(
"FuturePaymentExample",
"Probably the attempt to previously start the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
}
} else if (requestCode == REQUEST_CODE_PROFILE_SHARING) {
if (resultCode == Activity.RESULT_OK) {
PayPalAuthorization auth =
data.getParcelableExtra(PayPalProfileSharingActivity.EXTRA_RESULT_AUTHORIZATION);
if (auth != null) {
try {
Log.i("ProfileSharingExample", auth.toJSONObject().toString(4));

String authorization_code = auth.getAuthorizationCode();
Log.i("ProfileSharingExample", authorization_code);

sendAuthorizationToServer(auth);
Toast.makeText(
getApplicationContext(),
"Profile Sharing code received from PayPal", Toast.LENGTH_LONG)
.show();

} catch (JSONException e) {
Log.e("ProfileSharingExample", "an extremely unlikely failure occurred: ", e);
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("ProfileSharingExample", "The user canceled.");
} else if (resultCode == PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
Log.i(
"ProfileSharingExample",
"Probably the attempt to previously start the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
}
}
}
Expand Down
174 changes: 174 additions & 0 deletions docs/profile_sharing_mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
Profile Sharing Mobile Integration
==================================

This section will show how to obtain a user's authorized consent for profile sharing from their PayPal account.

_If you haven't already, see the [README](../README.md) for an initial overview and instructions for adding the SDK to your project._


Overview
--------

You must [obtain customer consent](#obtain-customer-consent) to share information from their PayPal account. How this works:

* On the PayPal Developer site...
1. Specify the pieces of information that you wish your customers to share with you.
* The PayPal Android SDK...
1. Presents UI for your user to authenticate using their PayPal account.
2. Asks your user to consent to [OAuth access token scope](http://tools.ietf.org/html/rfc6749#page-23) to use PayPal for profile sharing.
3. Returns an OAuth2 authorization code to your app.
* Your app...
1. Specifies the required scopes in SDK request
2. Receives an OAuth2 authorization code from the SDK.
3. Sends the authorization code to your server, which then [exchanges the code for OAuth2 access and refresh tokens](profile_sharing_server.md#obtain-oauth2-tokens).
4. Your server then [uses its OAuth2 tokens to request the relevant customer information from PayPal](profile_sharing_server.md).

**Notes:**
1. See `PayPalOAuthScopes` for a complete list of scope-values available to the PayPal Android SDK.
2. See [Log In with PayPal user attributes](https://developer.paypal.com/docs/integration/direct/identity/attributes/) for a complete list of available scope attributes.


Specify Desired Information for Sharing
---------------------------------------

1. Log in to the [PayPal Developer site](https://developer.paypal.com).
2. Select [your app](https://developer.paypal.com/webapps/developer/applications/myapps).
3. Under `APP CAPABILITIES` select `Log In with PayPal`, and click `Advanced options`.
4. Under `Information requested from customers` select the items ("scope attributes") you wish to have shared.
5. If you provide Privacy Policy and User Agreement URLs under `Links shown on customer consent page`, these will override the corresponding URLs that you provide below in the [`PayPalConfiguration` object](#obtain-customer-consent).


Obtain Customer Consent
-----------------------

The sample app provides a more complete example. However, at minimum, you must:

1. Add permissions to your `AndroidManifest.xml` file:
```xml
<!-- for most things, including card.io & paypal -->
<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"/>
```

1. Declare SDK service and activities in your `AndroidManifest.xml` file within the `<application>` tag:
```xml
<service android:name="com.paypal.android.sdk.payments.PayPalService"
android:exported="false" />

<activity android:name="com.paypal.android.sdk.payments.LoginActivity" />
<activity android:name="com.paypal.android.sdk.payments.PayPalProfileSharingActivity" />
<activity android:name="com.paypal.android.sdk.payments.ProfileSharingConsentActivity" />
```

1. Create a `PayPalConfiguration` object. This object allows you to configure various aspects of the SDK.

```java
private static PayPalConfiguration config = new PayPalConfiguration()

// Start with mock environment. When ready, switch to sandbox (ENVIRONMENT_SANDBOX)
// or live (ENVIRONMENT_PRODUCTION)
.environment(PayPalConfiguration.ENVIRONMENT_NO_NETWORK)

.clientId("<YOUR_CLIENT_ID>")

// Minimally, you will need to set three merchant information properties.
// These should be the same values that you provided to PayPal when you registered your app.
.merchantName("Hipster Store")
.merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy"))
.merchantUserAgreementUri(Uri.parse("https://www.example.com/legal"));
```

2. Start `PayPalService` when your activity is created and stop it upon destruction:

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

Intent intent = new Intent(this, PayPalService.class);

intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);

startService(intent);
}

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

3. Launch the PayPal Profile Sharing activity, for example, when a button is pressed:

```java
public void onProfileSharingPressed(View pressed) {
Intent intent = new Intent(SampleActivity.this, PayPalProfileSharingActivity.class);
intent.putExtra(PayPalProfileSharingActivity.EXTRA_REQUESTED_SCOPES, getOauthScopes());
startActivityForResult(intent, REQUEST_CODE_PROFILE_SHARING);
}
```

The `PayPalOAuthScopes` are initialized with a set of scope names:

```java
private PayPalOAuthScopes getOauthScopes() {
/* create the set of required scopes
* Note: see https://developer.paypal.com/docs/integration/direct/identity/attributes/ for mapping between the
* attributes you select for this app in the PayPal developer portal and the scopes required here.
*/
Set<String> scopes = new HashSet<String>(
Arrays.asList(PayPalOAuthScopes.PAYPAL_SCOPE_EMAIL, PayPalOAuthScopes.PAYPAL_SCOPE_ADDRESS) );
return new PayPalOAuthScopes(scopes);
}
```

4. Implement `onActivityResult()`:

```java
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
PayPalAuthorization auth = data
.getParcelableExtra(PayPalProfileSharingActivity.EXTRA_RESULT_AUTHORIZATION);
if (auth != null) {
try {
String authorization_code = auth.getAuthorizationCode();

sendAuthorizationToServer(auth);

} catch (JSONException e) {
Log.e("ProfileSharingExample", "an extremely unlikely failure occurred: ", e);
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("ProfileSharingExample", "The user canceled.");
} else if (resultCode == PayPalProfileSharingActivity.RESULT_EXTRAS_INVALID) {
Log.i("ProfileSharingExample",
"Probably the attempt to previously start the PayPalService had an invalid PayPalConfiguration. Please see the docs.");
}
}
```

5. Send the authorization response to your server in order to complete the process.

```java
private void sendAuthorizationToServer(PayPalAuthorization authorization) {

// TODO:
// Send the authorization response to your server, where it can exchange the authorization code
// for OAuth access and refresh tokens.
//
// Your server must then store these tokens, so that your server code can use it
// for getting user profile data in the future.

}
```


Next Steps
----------

Read [Profile Sharing Server-Side Integration](profile_sharing_server.md) to exchange the authorization code for OAuth2 tokens and retrieve the customer information from PayPal.
Loading

0 comments on commit e20293f

Please sign in to comment.