Documentation
PWLocal Android SDK
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 ?
- The customer clicks on the “Buy” button inside your application.
- The PWLocal SDK is called at this moment and opens application dialog with the list of payment systems.
- 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.
- 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
andprojectKey
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 type | Parameter |
String | key |
String | sign |
Integer | signVersion |
Long | timeStamp |
String | uid |
String | urlParameters |
String | secretKey |
String | |
Integer | evaluation |
String | firstname |
String | lang |
String | lastname |
String | locationAddress |
String | locationCity |
String | locationCountry |
String | locationState |
String | locationZip |
String | pingbackUrl |
String | paymentSystem |
String | sex |
String | successUrl |
String | widget |
String | birthday |
String | countryCode |
String | apiType |
Map<Integer, String> | externalIds |
Map<Integer, Float> | prices |
Map<Integer, String> | currencies |
LocalDefaultRequest
Data type | Parameter |
String | defaultGoodsId |
Map<Integer, String> | displayGoods |
Map<Integer, String> | hideGoods |
LocalFlexibleRequest
Data type | Parameter |
String | agExternalId |
String | agName |
Integer | agPeriodLength |
String | agPeriodType |
String | agPostTrialExternalId |
String | agPostTrialName |
Integer | agPostTrialPeriodLength |
String | agPostTrialPeriodType |
String | agPromo |
Integer | agRecurring |
Integer | agTrial |
String | agType |
String | currencycode |
Integer | hidePostTrialGood |
String | postTrialAmount |
String | postTrialCurrencycode |
Integer | showPostTrialNonRecurring |
Integer | showPostTrialRecurring |
Integer | showTrialNonRecurring |
Integer | showTrialRecurring |
Float | amount |
UserProfile
Data type | Parameter |
String | |
Long | registrationDate |
Long | birthday |
String | sex |
String | username |
String | firstname |
String | lastname |
String | city |
String | state |
String | address |
String | country |
String | zip |
String | membership |
Long | membershipDate |
String | registrationCountry |
String | registrationIp |
String | registrationEmail |
Boolean | registrationEmailVerified |
String | registrationName |
String | registrationLastname |
String | registrationSource |
Integer | loginsNumber |
Integer | paymentsNumber |
Double | paymentsAmount |
Integer | followers |
Integer | messageSent |
Integer | messageSentLast24h |
Integer | messageReceived |
Integer | interactions |
Integer | interactionsLast24h |
Float | riskScore |
Integer | complaints |
Boolean | wasBanned |
Integer | deliveredProducts |
Integer | canceledPayments |
Float | rating |
Integer | registrationAge |
Boolean | enable3dSecure |
For more information, please see User Profile API