Paymentwall website uses cookies to store your browsing preferences on your device. However, cookies do not collect personal information.

For more information about how we use cookies, check our cookie policy

Close

Documentation

New Documentation Getting Started API Libraries APIs Checklists Flows Integrations Mobile SDKs Reference Smart TV SDK SpiderPipe Testing Payments
Contacts
If you still have questions regarding integration, please email us at devsupport@paymentwall.com

PWLocal Android SDK

Attachments

PWLocal Android SDK

Introduction

Do you need to have an ability to accept payments from mobile users in different countries, considering which payment methods fit best? PWLocal is a global payment gateway that makes it easy to accept payments from customers in more than 200 countries with 100+ alternative payment options. PWLocal Android SDK will become a native part of your application, it eliminates the necessity to open a web browser for payments, as a result you will receive a higher conversions rate. All you have to do is import the library into your Android project and start using our SDK to accept in-app payments. It is quick and easy! We'll guide you through the process here.

How does it work ?

  1. The customer clicks on the “Buy” button inside your application.
  2. The PWLocal SDK is called at this moment and opens application dialog with the list of payment systems.
  3. User chooses a payment system and clicks on “Buy”. After it, a new application dialog opens. It would be a "thank you" screen or a dialog for providing payment details, such as credit card number, if needed.
  4. The payment is completed and your callback function is triggered to handle its result. Your backend will be also notified about it.

Requirements

Android 2.2 (API Level 8) and above

Credentials

Your mobile integration requires a Project key.
You can obtain these Paymentwall API credentials in the application settings of your Merchant Account at paymentwall.com

Add SDK

Our SDK is delivered as a JAR package so just drop it into your project. It also requires android-support-v4.jar, if your project doesn’t have it, please add one.

Modify your AndroidManifest.xml

Add required permission

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

Add required activity

<activity
    android:name="com.paymentwall.sdk.pwlocal.ui.PwLocalActivity"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:theme="@android:style/Theme.Translucent" />

First payment

Import

import com.paymentwall.sdk.pwlocal.message.*;
import com.paymentwall.sdk.pwlocal.ui.PwLocalActivity;
import com.paymentwall.sdk.pwlocal.utils.Key;
import com.paymentwall.sdk.pwlocal.utils.PaymentMethod;
import com.paymentwall.sdk.pwlocal.utils.ResponseCode;
import com.paymentwall.sdk.pwlocal.utils.MessageUtils;

Create a request

We have 2 types of PWLocal payment request: LocalDefaultRequest and LocalFlexibleRequest We support 3 API type: ApiType.VIRTUAL_CURRENCY, ApiType.DIGITAL_GOODS, ApiType.CART For more information, please refer to: https://www.paymentwall.com/en/documentation/Digital-Goods-API/710

Defined request

We defined 2 types of request: LocalDefaultRequest and LocalFlexibleRequest. You can simply use setters to set required parameters. Please note that all the parameters are changed from under_score to camelCase format. Your signature will be calculated automatically if signVersion and secret are set.

Example
LocalDefaultRequest request = new LocalDefaultRequest();
request.setKey(PROJECT_KEY);
request.setUid(USER_ID);
request.setWidget(WIDGET_TYPE);
request.setApiType(API_TYPE);
request.setSecretKey(SECRET_KEY);
request.setSignVersion(3);
request.setMobileDownloadLink(YOUR_MOBILE_APP_DOWNLOAD_LINK);

Custom request

If our defined request does not match your need. We also supported Map-like query. It follows the parameters in https://www.paymentwall.com/en/documentation/Digital-Goods-API/710. Most of the parameters are already defined in Const.P class. Your signature will be calculated automatically if signVersion and secret are set.

Example
CustomRequest request = new CustomRequest();
request.put(Const.P.KEY, PROJECT_KEY);
request.put(Const.P.WIDGET, "m2_1");
request.put(Const.P.EVALUATION, "1");
request.put(Const.P.UID, "testuser");
request.put(Const.P.AG_EXTERNAL_ID, "testitem");
request.put(Const.P.AG_NAME, "Test item");
request.put(Const.P.CURRENCYCODE, "USD");
request.put(Const.P.AMOUNT, "0.5");
request.put(Const.P.AG_TYPE, "fixed");
request.setMobileDownloadLink(YOUR_MOBILE_APP_DOWNLOAD_LINK);
request.setSecretKey(SECRET_KEY);
request.setSignVersion(3);

Widget signature

Using Widget signature secures your widget and prevents unauthorized access.

Auto signing (unsecured)

Normally, autoSigned is turned off. You can turn it on by setting a secretKey. Your widget call will be automatically signed.

request.setSignVersion(3);
request.setSecretKey("Your Secret Key");

By using this method, your secretKey can be compromised against reverse-engineering. Please consider storing it in a secured place.

Manual signing

Storing secretKey on your own backend lower your risk of exposing it. Signing your request remotely is recommended to secure your project. Please note that some parameters are added by default. Use this method to get all required parameters for signing

/// default parameters
Map<String,String> defaultParameters = MessageUtils.getDefaultParameters();

Or

// do this after setting all parameters
Map<String,String> generatedParameters = MessageUtils.getDefaultParameters(request);

Sorting parameters alphabetically (ie: using a TreeMap) before signing is required to work with PWLocal SDK.

Defined request
request.setSignVersion(3);
request.setSign("Signature Value");
Custom request
request.setSignVersion(3);
request.put(Const.P.SIGN,"Signature Value");

Please see Signature calculation for signing algorithm.

User Profile API

PWLocal SDK supports User Profile API. Setting UserProfile can be done by simply put it in a Defined Request as following

UserProfile userProfile = new UserProfile();
//Please set user email and registration date here
userProfile.setEmail(USER_EMAIL);
userProfile.setRegistrationDate(REGISTRATION_DATE);
request.setUserProfile(userProfile);

Or to a Custom request

UserProfile userProfile = new UserProfile();
//Please set user email and registration date here
userProfile.setEmail(USER_EMAIL);
userProfile.setRegistrationDate(REGISTRATION_DATE);
request.putAll(userProfile.toParameters());

Start PWLocal dialog

Defined request

Intent intent = new Intent(getApplicationContext(), PwLocalActivity.class);
//PaymentMethod.PW_LOCAL_DEFAULT or PaymentMethod.PW_LOCAL_FLEXIBLE
intent.putExtra(Key.PAYMENT_TYPE, PaymentMethod.PW_LOCAL_DEFAULT);
intent.putExtra(Key.PWLOCAL_REQUEST_MESSAGE, (Parcelable) request);
startActivityForResult(intent, PwLocalActivity.REQUEST_CODE);

Custom request

Intent intent = new Intent(getApplicationContext(), PwLocalActivity.class);
intent.putExtra(Key.CUSTOM_REQUEST_TYPE, ApiType.DIGITAL_GOODS);
intent.putExtra(Key.CUSTOM_REQUEST_MAP, request);
startActivityForResult(intent, PwLocalActivity.REQUEST_CODE);

Handle result

You can handle payment results by defining your callback function. We recommend syncing up with your server at this point to sync up user's balance, confirm purchased item etc. See the example:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if(requestCode==PwLocalActivity.REQUEST_CODE) {
    switch (resultCode) {
      case ResponseCode.CANCEL:
        break;
      case ResponseCode.ERROR:
        String errorMessage = data.getStringExtra(Key.SDK_ERROR_MESSAGE);
        break;
      case ResponseCode.SUCCESSFUL:
        break;
      default:
        break;
    }
  }
}

resultCode code can have one of the following values:

ResponseCode.SUCCESSFUL: the user has completed the payment

ResponseCode.CANCEL: the user has aborted the payment

ResponseCode.ERROR: the payment cannot be done due to some error:

  • Network error
  • Invalid supplying request

If widget call request is set, the request is also returned via data

Defined request

if (data != null && data.hasExtra(Key.PWLOCAL_REQUEST_MESSAGE)) {
    LocalRequest request = data.getParcelableExtra(Key.PWLOCAL_REQUEST_MESSAGE);
}

Custom request

if (data!=null && data.hasExtra(Key.CUSTOM_REQUEST_MAP)) {
    CustomRequest parameters = data.getParcelableExtra(Key.CUSTOM_REQUEST_MAP);
}

Payment Status API utils

Our SDK also supports Payment Status API.

Create PaymentStatusRequest

Unsigned call

PaymentStatusRequest request = new PaymentStatusRequest.Builder().setQuery(
                        PROJECT_KEY, // your project key
                        USER_ID, // user id
                        AG_EXTERNAL_ID) // external id of the product
                        .build();

Signed call

PaymentStatusRequest request = new PaymentStatusRequest.Builder().setQuery(
                        PROJECT_KEY, // your project key
                        USER_ID, // user id
                        AG_EXTERNAL_ID // external id of the product
                        SECRET_KEY, // project secret key
                        3) // sign version
                        .build();

Unsigned call can be enabled by request. Please inform our bizdev. Please note that, enabling unsigned Payment Status API call can make your information less secured.

Get payment status

PaymentStatusUtils.getPaymentStatus(request, new PaymentStatusCallback(){
    @Override
    public void onError(Exception e) {
    // Handle error
    }

    @Override
    public void onSuccess(List<PaymentStatus> result) {
    // Handle the result
    }
});

Payment Status in activityResult

Experimental feature We also return PaymentStatus in activityResult if your call meets 4 following requirements:

  • It's a flexible widget call (custom or defined request)
  • It has agExternalId, uid and projectKey set
  • Payment Status extra is enable in request Intent
    intent.putExtra(Key.ENABLE_PAYMENT_STATUS, true);
  • There is only 1 returned Payment Status

The returned Payment Status can be get from onActivityResult callback

Bundle paymentStatusBundle = data.getBundleExtra(Key.RESULT_PAYMENT_STATUS);
if (paymentStatusBundle != null && paymentStatusBundle.containsKey(Key.PAYMENT_STATUS_IS_SUCCESSFUL)) {
    boolean successful = paymentStatusBundle.getBoolean(Key.PAYMENT_STATUS_IS_SUCCESSFUL);
    if (successful) {
        PaymentStatus status = paymentStatusBundle.getParcelable(Key.PAYMENT_STATUS_MESSAGE);
    } else {
        Exception e = (Exception) paymentStatusBundle.getSerializable(Key.PAYMENT_STATUS_EXCEPTION);
}

Pingback handling

After each successful payment we will notify your server about it. We recommend to use this feature as it is the most reliable way to know when the payment went through. Even if your application crashes for some reason, your server will still be notified, so you can sync up later. Please use pingback processing documentation for more information.

Appendix

Proguard configuration

If Proguard is used, please kindly add these lines to your proguard configuration file

-keep class com.paymentwall.sdk.pwlocal.** { *; }
-dontwarn com.paymentwall.sdk.pwlocal.**

Supported parameters

Here's the list of supported parameters in defined requests

Common parameters

Data typeParameter
Stringkey
Stringsign
IntegersignVersion
LongtimeStamp
Stringuid
StringurlParameters
StringsecretKey
Stringemail
Integerevaluation
Stringfirstname
Stringlang
Stringlastname
StringlocationAddress
StringlocationCity
StringlocationCountry
StringlocationState
StringlocationZip
StringpingbackUrl
StringpaymentSystem
Stringsex
StringsuccessUrl
Stringwidget
Stringbirthday
StringcountryCode
StringapiType
Map<Integer, String>externalIds
Map<Integer, Float>prices
Map<Integer, String>currencies

LocalDefaultRequest

Data typeParameter
StringdefaultGoodsId
Map<Integer, String>displayGoods
Map<Integer, String>hideGoods

LocalFlexibleRequest

Data typeParameter
StringagExternalId
StringagName
IntegeragPeriodLength
StringagPeriodType
StringagPostTrialExternalId
StringagPostTrialName
IntegeragPostTrialPeriodLength
StringagPostTrialPeriodType
StringagPromo
IntegeragRecurring
IntegeragTrial
StringagType
Stringcurrencycode
IntegerhidePostTrialGood
StringpostTrialAmount
StringpostTrialCurrencycode
IntegershowPostTrialNonRecurring
IntegershowPostTrialRecurring
IntegershowTrialNonRecurring
IntegershowTrialRecurring
Floatamount

UserProfile

Data typeParameter
Stringemail
LongregistrationDate
Longbirthday
Stringsex
Stringusername
Stringfirstname
Stringlastname
Stringcity
Stringstate
Stringaddress
Stringcountry
Stringzip
Stringmembership
LongmembershipDate
StringregistrationCountry
StringregistrationIp
StringregistrationEmail
BooleanregistrationEmailVerified
StringregistrationName
StringregistrationLastname
StringregistrationSource
IntegerloginsNumber
IntegerpaymentsNumber
DoublepaymentsAmount
Integerfollowers
IntegermessageSent
IntegermessageSentLast24h
IntegermessageReceived
Integerinteractions
IntegerinteractionsLast24h
FloatriskScore
Integercomplaints
BooleanwasBanned
IntegerdeliveredProducts
IntegercanceledPayments
Floatrating
IntegerregistrationAge
Booleanenable3dSecure

For more information, please see User Profile API

This page needs JavaScript
Your browser is
not supported anymore.
Please update to the more recent one.
This page needs JavaScript
This page needs JavaScript.
Please enable it in your browser settings and try again.
We use cookies on this website to make your browsing experience better. By using the Paymentwall website you agree to our Cookies Policy.