Stripe - Android Framework
UPDATE: As of February 14, 2024 a new version of the SDK is available. Documentation for the new version of the SDK (2.1.0) is available here.
Models
ECPDevice
Property | Type | Description |
---|---|---|
id_number | String | Id (serial) number of device. |
manufacturer | String | Manufacturer/brand of device. |
model | String | Model of device. |
battery_percentage | String | Battery percentage of device between 0-100%. |
reader | T | Reader object specified by the processor |
ECPPaymentParameters
NOTE: There are objects in the SDK for other processors, which are not yet supported.
Property | Type | Description |
---|---|---|
amount | String | Required. Amount to charge. Must be a positive number. Specify using the following format: "1234.50". Do not utilize commas (,), negative numbers, or more than 2 decimal points. The following formats will also be accepted, however we encourage consumers to specify the entire amount as listed above (i.e. "1234.50"): "1234" for $1234.00 "1234.0" for $1234.00 "1234.5" for $1234.5 |
paymentDescription | String | Optional. A string to be displayed on your customerโs credit card statement. This may be up to 22 characters. The statement descriptor must contain at least one letter, may not include <>"' characters, and will appear on your customerโs statement in capital letters. Non-ASCII characters are automatically stripped. While most banks and card issuers display this information consistently, some may display it incorrectly or not at all. |
paymentDescriptionSuffix | String | Optional. A string to specify details about the transaction so your customer can understand it clearly on their statement. The suffix is concatenated with the statementDescriptor, the * symbol, and a space to form the complete statement descriptor that your customer sees. Maximum 22 characters for the final concatenated descriptor. |
currency | String | Optional. Default: "usd". Type of currency to be collected. Only USD supported at this time (default). |
external_id | String | Optional. <= 50 characters. Unique identifier for the payment in merchant or partner's system. |
duplicate_check | String | WORLDPAY/EXPRESS ONLY - NOT SUPPORTED AT THIS TIME Optional. Default:"enabled" Valid values: "enabled", "disabled". Indicates the duplicate check mode. |
capture | String | IDYNAMO ONLY - NOT SUPPORTED AT THIS TIME Optional. Possible values: "completed_sale" "auth_until_capture" "tip_adjustment". 'completed_sale' (default) will authorize and capture the sale at the specified amount. 'auth_until_capture' requires the capture endpoint for the payment to be added to a settlement batch. 'tip_adjustment' allows for the tip_adjustment endpoint to be called up until just prior to the batch close time. |
allow_partial_approvals | boolean | WORLDPAY/EXPRESS ONLY - NOT SUPPORTED AT THIS TIME Optional. Default: FALSE. If true, allows partial approvals. Most useful for gift cards with limited funds. |
ECPSaleResponse
Property | Type | Description |
---|---|---|
transaction_id | String | Unique Id of transaction. |
acqurier_message | String | Acquirer message returned. Do not base application logic on this message as it may change without notice. |
authorization_code | String | Acquirer Authorization code. |
approved_amount | String | Amount approved. |
batch_id | Integer | Settlement batch id (card only). Value will be null for Stripe processed payments. |
card | ECPCardData | Card response |
outcome | ECPSaleOutcome | Sale outcome |
emv | ECPEmvData | EMV response data if present |
entry_mode | String | Entry mode of transaction |
ECPSaleOutcome
Property | Type | Description |
---|---|---|
result | String | Result of transaction request. Valid values "success", "failed", "declined" |
code | String | 4-digit PaySimple result code. |
outcome_description | String | Description of decline, failure, or success. |
ECPCardData
Property | Type | Description |
---|---|---|
card_brand | String | Card brand type. |
last4 | String | Last 4 digits of card number. |
card_holder_name | String | Name of cardholder |
expiration_month | int | Month of card expiration |
expiration_year | int | Year of card expiration in 4 digit format. |
ECPEmvData
Property | Type | Description |
---|---|---|
application_identifier | String | Application Identifier. |
application_preferred_name | String | Application Preferred Name. |
application_label | String | Application Label. Value will be null for Stripe payments. |
application_cryptogram | String | Cryptogram value. |
authorization_response_code | String | Authorization Response Code. |
authorization_response_message | String | Authorization Response Message. |
is_pin_verified | boolean | Whether or not the result is pin verified. |
Client Token Interface
Authorization via client token is required to use this SDK. In this SDK, we have introduced the concept of a client token service. The client token service ensures the SDK is able to associate and authenticate with the proper merchant / client for each use.
Before integrating to our SDK, you should create an endpoint on your secure backend server which returns the proper PaySimple client token for a particular PaySimple user that you are trying to use the SDK with. How you map your application's users to a PaySimple user is up to you in your backend - you just need to be sure to get a proper PaySimple token tied to the user you would like to utilize the SDK for each time you initialize. The type of authorization token currently supported will be https://documentation.paysimple.com/v2019/docs/authorization#client-token-authorization-rarely-used .
Consumers will implement a client token interface to help out with client token authentication. This client token interface for the Shared ECP SDK is called ClientTokenProvider.
Consumers will create a class which implements ClientTokenProvider.
See below for the structure of ClientTokenProvider
ClientTokenProvider (Interface)
Property | Type | Description |
---|---|---|
void getClientToken(ClientTokenProviderCallback callback) | Interface Method | Method implemented by consumer to retrieve client token and pass result/error through the ClientTokenProviderCallback, so the ECP SDK can fetch client tokens and utilize them when needed. When implemented correctly, getClientToken should retrieve the PaySimple client token you would like to use for a particular user from your secure backend. If you successfully retrieve a client token, pass it back through the callback.onComplete method with a null error. If you have an error retrieving a client token, pass back a null value for the token and a new ECPSdkCallbackError for the error in the callback.OnComplete method. Implementation examples will be shown further below. |
ClientTokenProviderCallback
Property | Type | Description |
---|---|---|
void onComplete(String clientToken, ECPSdkCallbackError error) | Interface Method | Callback provided to utilize alongside getClientToken to inform the SDK of the client token and/or client token error. Upon successful retrieval, call onComplete with a valid client token and a null error. Upon an error during retrieval, call onComplete with a null client token and a new ECPSdkCallbackError. |
Example Implementation
TokenService.java
import com.evercommerceandroid.evercommercepaymentsandroidsdk.clienttoken.ClientTokenProvider;
import com.evercommerceandroid.evercommercepaymentsandroidsdk.clienttoken.ClientTokenProviderCallback;
import com.evercommerceandroid.evercommercepaymentsandroidsdk.models.ECPSdkCallbackError;
// any other needed imports
public class TokenService implements ClientTokenProvider {
public TokenService() {
}
@Override
public void getClientToken(ClientTokenProviderCallback callback) {
try {
ClientTokenManager clientTokenManager = new ClientTokenManager();
clientTokenManager.getAndOutputToken(new TokenManager.TokenResponseListener() {
@Override
public void onError(Error error) {
callback.onComplete(null, new ECPSdkCallbackError("Failed to fetch client token in TokenService"));
}
@Override
public void onResponse(String token) {
callback.onComplete(token, null);
}
});
}catch (Exception e) {
callback.onComplete(null, new ECPSdkCallbackError("Failed to fetch client token. Exception caught."));
}
}
}
MainActivity.java (or anywhere that calls initializeSdk), make sure you are creating a new instance of your TokenService set up with any information that you need for determining the proper PaySimple user you should be fetching a client token for. Then pass the tokenService as part of the initialize SDK function, and we will utilize the token service to fetch client tokens when needed.
TokenService tokenService = new TokenService();
_ecpSdk = SharedECPSdk.getInstance(StripeLandingActivity.this);
HashSet<ECPEventType> subscribedEvents = new HashSet<ECPEventType>();
subscribedEvents.add(ECPEventType.CONNECTION_CHANGED_EVENT);
subscribedEvents.add(ECPEventType.DEVICE_BATTERY_EVENT);
subscribedEvents.add(ECPEventType.DEVICE_CARD_EVENT);
subscribedEvents.add(ECPEventType.DEVICE_MESSAGE_EVENT);
subscribedEvents.add(ECPEventType.CONFIG_STATUS_EVENT);
subscribedEvents.add(ECPEventType.CONFIG_PROGRESS_EVENT);
_ecpSdk.initializeSdk(StripeLandingActivity.this, environment, tokenService, subscribedEvents, this, new InitializeSdkCallback() {
@Override
public void onComplete(boolean isInitializeSdkSuccess, ECPSdkCallbackError errorResponse) {
// code after initialize here
}
});
The Client Token interface getClientToken method you implement will be called by our SDK as needed during various actions which require PaySimple authorization.
ECPEventType (enum)
Event types to be used to help consumers specify which events they would like to listen to when calling Initialize SDK. The following values can be used for ECPEventType:
ALL
CONFIG_STATUS_EVENT
CONFIG_PROGRESS_EVENT**
CONNECTION_CHANGED_EVENT
DEVICE_BATTERY_EVENT
DEVICE_CARD_EVENT
DEVICE_MESSAGE_EVENT
These values are accessible when using our Shared ECP SDK. See sample code below:
HashSet<ECPEventType> subscribedEvents = new HashSet<ECPEventType>();
// use ECPEventType.ALL if you would like to subscribe to all events by default.
// subscribedEvents.add(ECPEventType.ALL);
subscribedEvents.add(ECPEventType.CONNECTION_CHANGED_EVENT);
subscribedEvents.add(ECPEventType.DEVICE_BATTERY_EVENT);
subscribedEvents.add(ECPEventType.DEVICE_CARD_EVENT);
subscribedEvents.add(ECPEventType.DEVICE_MESSAGE_EVENT);
subscribedEvents.add(ECPEventType.CONFIG_STATUS_EVENT);
subscribedEvents.add(ECPEventType.CONFIG_PROGRESS_EVENT);
Class Methods
Shared Instance
Returns a shared instance of the ECPSdk service. If you would like, you can store this in a variable to later be accessed by your class.
public static synchronized ISharedECPSdk getInstance(Context context);
Example Implementation:
private ISharedECPSdk _ecpSdk;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_ecpSdk = SharedECPSdk.getInstance(MyActivity.this);
}
Instance Methods
Important
As best practice, make sure the completion handler of one operation within the ECPSdk is called prior to attempting to execute an additional operation, to avoid unintended behavior. One exception to this may be using stopCurrentFlow to cancel a payment.
Initialize SDK
No instance methods should be used until the SDK has been successfully initialized. One exception to this case may be checking Is Initialized if needed for your application's flow.
Initializes the SDK. Provides a callback to determine the result of the SDK initialization. Returns isInitializedSuccess = true and error = null if initialization occurred without error. Consumers must initialize the SDK prior to any other SDK actions. User must pass in context, environment, ClientTokenProvider, list of events they would like to subscribe to, ECPSdkListener, and an InitializeSdkCallback.
void initializeSdk(Context context,
ECPEnvironment environment,
ClientTokenProvider clientTokenBlock,
HashSet<ECPEventType> subscribedEvents,
ECPSdkListener listener, InitializeSdkCallback callback);
Property | Type | Description |
---|---|---|
context | Context | Required. Android context. |
environment | ECPEnvironment | Required. Environment to use. Possible values: "SBX" for sandbox or "PROD" for production |
clientTokenBlock | ClientTokenProvider | Required. ClientTokenProvider which returns a PaySimple client token and an error so the SDK can hook into your client/merchant. |
subscribedEvents | HashSet | Set of events consumer would like to listen to. If a null or empty set is passed in, by default user will subscribe to all events. ECPEventType.ALL will also subscribe to all events, if it is present in the HashSet. If you only want to listen to specific events, please specify those events using ECPEventType. For example, if you only wanted to listen to ECPDeviceMessageEvent and ECPConnectionChangedEvent, you would pass in a set as that has been initialized as follows: HashSet subscribedEvents = new HashSet(); subscribedEvents.add(ECPEventType.DEVICE_MESSAGE_EVENT); subscribedEvents.add(ECPEventType.CONNECTION_CHANGED_EVENT); |
listener | ECPSdkListener | This is the listener that will send events from the sdk to your application. |
callback | InitializeSdkCallback | Required. Upon execution passes back isSdkInitialized to provide information on the result of initialization. Also passes ECPSdkCallbackError reference to pass back error information in case of initialization issue. |
Example Implementation:
public class StripeLandingActivity extends AppCompatActivity implements ECPSdkListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
ECPEnvironment environment = ECPEnvironment.PROD;
HashSet<ECPEventType> subscribedEvents = new HashSet<ECPEventType>();
subscribedEvents.add(ECPEventType.ALL);
TokenService tokenService = new TokenService();
_ecpSdk.initializeSdk(StripeLandingActivity.this, environment, tokenService, subscribedEvents, this, new InitializeSdkCallback() {
@Override
public void onComplete(boolean isInitializeSdkSuccess, ECPSdkCallbackError errorResponse) {
// Handle callback
}
});
}
}
Subscribe To Events
This adds an object to the list of listeners that will receive notifications of events from the ECPSdk. The object must implement the ECPSdkListener interface. This does not change the events that are sent by the ECPSdk (this is setup in the Initialization as outlined above). See the Delegates / Listeners / Events section below for more information on handling events.
void subscribeToEvents(ECPSdkListener ecpSdkListener, ECPCallback callback);
Property | Type | Description |
---|---|---|
ecpSdkListener | ECPSdkListener | Required. An object that implements the ECPSdkListener interface. |
ecpCallback | ECPCallback | Required. Callback which indicates the subscribe to events process has finished. onComplete will be called and will return a boolean indicating whether the processes completed successfully. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the subscribe to events process, so errors can be handled appropriately. |
Example Implementation:
// somewhere in your class you have stored the sdk, accessing it via sharedECPSdk variable
// the class this is called from in this example implements ECPSdkListener.
_ecpSdk.subscribeToEvents(this, new ECPCallback() {
@Override
public void onComplete(boolean success, ECPSdkCallbackError error) {
Log.i(TAG, "Subscribed to events: " + success);
}
});
Unsubscribe From Events
This removes an object from the list of listeners that will receive notifications of events from the ECPSdk. The object must implement the ECPSdkListener interface.
void unsubscribeFromEvents(ECPSdkListener ecpSdkListener, ECPCallback ecpCallback);
Property | Type | Description |
---|---|---|
ecpSdkListener | ECPSdkListener | Required. An object that implements the ECPSdkListener interface. |
ecpCallback | ECPCallback | Required. Callback which indicates the unsubscribe process has finished. onComplete will be called and will return a boolean indicating whether the unsubscribe processes completed successfully. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the unsubscribe from events process, so errors can be handled appropriately. |
Example Implementation:
// somewhere in your class you have stored the sdk, accessing it via sharedECPSdk variable
// the class this is called from in this example implements ECPSdkListener.
_ecpSdk.unsubscribeFromEvents(this, new ECPCallback() {
@Override
public void onComplete(boolean success, ECPSdkCallbackError error) {
Log.i(TAG, "Unsubscribed from events: " + success);
}
});
Is Initialized
Returns boolean to indicate if the SDK has been initialized.
boolean isInitialized();
Example Implementation:
// somewhere in your class you have stored the sdk, accessing it via sharedECPSdk variable
if (_ecpSdk.isInitialized()) {
// Your logic here
}
Reset SDK
Clears out SDK data. Clears processor data, client token provider data, event subscriptions, any data that was setup in Initialize SDK. Disconnects device. Allows consumer to start fresh with a reset instance of the SDK to help with changing users, clearing config.
void resetSdk(ResetSdkCallback resetSdkCallback);
Property | Type | Description |
---|---|---|
resetSdkCallback | ResetSdkCallback | Required. Callback which indicates the reset process has finished. onComplete will be called and will return a boolean indicating whether the reset processes completed successfully. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the reset process, so errors can be handled appropriately. |
Example Implementation:
private void resetSdk(){
_ecpSdk.resetSdk(new ResetSdkCallback() {
@Override
public void onComplete(boolean isReset, ECPSdkCallbackError error) {
// handle callback
}
});
}
Discover Devices
Discovers devices powered on and within range of the Android device to be used with the SDK. Currently only officially supported for the Stripe M2 Reader Device. Note - battery percentage on the ECPDevice objects coming back from Discover Devices may appear as null. Battery percentage cannot reliably be reported on until a consumer connects to a device. If you have another brand of bluetooth reader turned on and in range, discover devices may show the device. However, only Stripe M2 will currently work with Connect Device.
Mobile device settings warning (Stripe M2)
For the Stripe M2 Reader, users should not use the own mobile device's settings when pairing with an M2 reader using the SDK. Pairing the reader through your mobile device's settings may make the reader unavailable to connect through our SDK. Please rely on our ECPSdk to help guide the connection process.
void discoverDevices(int scanTime, DiscoverCallback discoverCallback);
Property | Type | Description |
---|---|---|
scanTime | int | Required. Amount of time in seconds you would like to attempt to scan to discover devices. If 0 is passed in, the scanTime will default to a value of 5. |
discoverCallback | DiscoverCallback | Required. Callback which indicates the discover process has finished. onComplete will be called with an ArrayList of type ECPDevice indicating all devices that were successfully discovered. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the discover process, so errors can be handled appropriately. |
Example Implementation (in the example below you can also see how information in discoverDevices is directly used to then call in to connectDevice):
_ecpSdk.discoverDevices(5, new DiscoverCallback<Reader>() {
@Override
public void onComplete(ArrayList<ECPDevice<Reader>> devices, ECPSdkCallbackError error) {
if (error == null && devices != null && devices.size() > 0) {
String[] deviceSerials = new String[devices.size()];
StringBuilder devicesFoundInfo = new StringBuilder("Found the following devices on Scan:");
for (int i = 0; i < devices.size(); i++) {
deviceSerials[i] = devices.get(i).id_number;
devicesFoundInfo = devicesFoundInfo.append("\n" + " Id: " + devices.get(i).id_number +
" Manufacturer: " + devices.get(i).manufacturer +
" Model: " + devices.get(i).model +
" Battery Percentage: " + devices.get(i).battery_percentage + "\n");
}
String finalDevicesFoundString = devicesFoundInfo.toString();
runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(StripeLandingActivity.this);
builder.setTitle("Devices");
responseView.setText(finalDevicesFoundString);
builder.setItems(deviceSerials, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// access clicked deviceSerial through deviceSerials[i]
java.util.Optional<ECPDevice<Reader>> ecpDeviceOptional = devices.stream().filter(p -> p.id_number.equals(deviceSerials[i])).findFirst();
if (!ecpDeviceOptional.isPresent()) {
Toast.makeText(StripeLandingActivity.this, "Error connecting to device id: " + deviceSerials[i], Toast.LENGTH_SHORT).show();
return;
}
ECPDevice<Reader> ecpDevice = ecpDeviceOptional.get();
_ecpSdk.connectDevice(ecpDevice, new ConnectCallback() {
@Override
public void onComplete(boolean connected, ECPSdkCallbackError error) {
Log.i(TAG, "connected: " + connected);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (connected) {
Toast.makeText(StripeLandingActivity.this, "Device connected!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(StripeLandingActivity.this, "Device connection failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
});
builder.show();
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText("No devices found to report info on from scan");
AlertDialog.Builder builder = new AlertDialog.Builder(StripeLandingActivity.this);
if (error != null && error.errorDescription != null) {
builder.setTitle("No devices found! Discover error was " + error.errorDescription);
} else {
builder.setTitle("No devices found!");
}
builder.show();
}
});
}
}
});
Connect Device
Currently only officially supported for Stripe M2 Reader device. Connects to the card reader device and prepares the device to take payments, fire off events, and report information. A reader can only connect to one instance of the SDK at a time. If a device is already connected and another connection attempt is made, the ConnectCallback will return true. If you want to connect to a different device, be sure to disconnect from any connected devices first. Note - a reader may need to update on the connect process. The reader will not finish the connect process until required updates succeed. If a reader needs to update, ensure your reader is charged greater than 50 percent. Monitor ECPDeviceConfigStatusEvent and ECPDeviceConfigProgressEvent to track update status.
<T> void connectDevice(ECPDevice<T> ecpDevice, ConnectCallback connectCallback);
Property | Type | Description |
---|---|---|
ecpDevice | ECPDevice | Device object which you would like to attempt to connect to. This should be a recently discovered device from the Discover Devices method. Note - this device must be charged and turned on in order to connect. The generic represents the reader specific to the processor. For example, the Stripe reader would come from the Stripe SDK in com.stripe.stripeterminal.external.models.Reader. |
connectCallback | ConnectCallback | Required. Callback which indicates the connect process has finished. onComplete will be called and will return boolean indicating whether the connection processes completed successfully. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the connect process, so errors can be handled appropriately. |
Example Implementation: See the example below. This example assumes that the discoverDevices method has been called and a device was found. The selected discovered device from the devices array returned from discoverDevices is then passed into the connectDevice method.
_ecpSdk.connectDevice(ecpDevice, new ConnectCallback() {
@Override
public void onComplete(boolean connected, ECPSdkCallbackError error) {
Log.i(TAG, "connected: " + connected);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (connected) {
Toast.makeText(StripeLandingActivity.this, "Device connected!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(StripeLandingActivity.this, "Device connection failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
});
Low Battery / Device Powered off Troubleshooting
When connecting to a reader for use, ensure the reader is charged greater than 20 percent to avoid unintended behavior due to low battery. Also ensure the device is turned on. If you attempt to connect to a reader with low battery or a powered off reader, you may notice connectDevice or the SDK stalling. If stalling behavior is noticed, try the following trouble shooting steps:
- Manually power down M2 reader device.
- Manually turn M2 reader device back on.
- Reset the SDK.
- Initialize SDK.
- Attempt to use SDK again.
If all else fails, force close your application, ensure your reader device is charged/powered on, and try again.
Disconnect Device
Disconnects the currently connected device.
void disconnectDevice(DisconnectCallback disconnectCallback);
Property | Type | Description |
---|---|---|
disconnectCallback | DisconnectCallback | Required. Callback which indicates the disconnect device process has finished. onComplete will be called and will return a boolean indicating whether the disconnect processes completed successfully. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the disconnect process, so errors can be handled appropriately. |
Example Implementation:
_ecpSdk.disconnectDevice(new DisconnectCallback() {
@Override
public void onComplete(boolean didDisconnect, ECPSdkCallbackError error) {
// Your logic here
}
});
Make Sale
Makes a sale for the amount specified. This requires that the SDK is initialized and that the Client Token Service is set up correctly in order to retrieve a current client token for communication with PaySimple.
void makeSale(ECPPaymentParameters parameters, MakeSaleCallback makeSaleCallback);
Property | Type | Description |
---|---|---|
parameters | ECPPaymentParameters | Required. The parameters used to create the payment. |
makeSaleCallback | MakeSaleCallback | Required. Upon execution calls back onComplete. Passes back a boolean to provide information on if the sale flow completed (Note: this can return true even if the payment fails. This only indicates that the flow completed successfully). Passes back an ECPSaleResponse object with information about the payment. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the sale process, so errors can be handled appropriately. |
Example implementation:
ECPPaymentParameters params = new ECPPaymentParameters();
params.amount = "100.00";
params.external_id = "TestExternalId";
params.paymentDescription = "Test Description";
params.paymentDescriptionSuffix = "Test Suffix";
_ecpSdk.makeSale(params, new MakeSaleCallback() {
@Override
public void onComplete(boolean success, ECPSaleResponse saleResponse, ECPSdkCallbackError error) {
Log.i(TAG, "make sale completed. Success: " + success);
}
});
Stop Current Flow
Stops a payment from completing. This can be done before the payment method is collected. Once the payment method is collected, the payment flow will run to completion.
void stopCurrentFlow(ECPCallback callback);
Property | Type | Description |
---|---|---|
callback | ECPCallback | Required. Callback which indicates the stop current flow process has finished. onComplete will be called and will return a boolean indicating whether the stop current flow process completed successfully. Also reports back an ECPSdkCallback error to pass back any error information that occurs during the stop current flow process, so errors can be handled appropriately. |
Example implementation:
_ecpSdk.stopCurrentFlow(new ECPCallback() {
@Override
public void onComplete(boolean success, ECPSdkCallbackError error) {
// Your logic here
}
});
Get Device Info
Returns information about the connected device.
void getDeviceInfo(DeviceInfoCallback deviceInfoCallback);
Propetty | Type | Description |
---|---|---|
deviceInfoCallback | DeviceInfoCallback | Required. Upon execution calls back onComplete with device information. Passes back isDeviceConnected to provide information on if a device is currently connected to the SDK. Passes back an ECPDevice object with up to date properties for the specific device. Also passes back an ECPSdkCallbackError reference in case of an issue with getDeviceInfo. |
Example Implementation:
deviceInfoBtn.setOnClickListener(v -> {
_ecpSdk.getDeviceInfo(new DeviceInfoCallback() {
@Override
public void onComplete(boolean isDeviceConnected, ECPDevice ecpDevice, ECPSdkCallbackError error) {
if (isDeviceConnected && ecpDevice != null && error == null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
StringBuilder deviceInfo = new StringBuilder("Get Device Info Result: \n "
+ "isDeviceConnected :" + isDeviceConnected + "\n"
+ "id: " + ecpDevice.id_number + "\n"
+ "manufacturer: " + ecpDevice.manufacturer + "\n"
+ "model: " + ecpDevice.model + "\n"
+ "battery_percentage: " + ecpDevice.battery_percentage + "\n"
+ "type: " + ecpDevice.reader.getClass());
responseView.setText(deviceInfo);
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
StringBuilder deviceInfoError = new StringBuilder("Error on Get Device Info: " + "\n"
+ "isDeviceConnected : " + isDeviceConnected + "\n"
+ "error: " + error.errorDescription != null ? error.errorDescription : "");
responseView.setText(deviceInfoError);
}
});
}
}
});
});
Delegates / Listeners / Events
The SDK provides an ECPSdkListener to help expose methods to report on SDK events. Currently, the ECPSdkListener provides one optional method void onDeviceEvent(ECPSdkEvent event) . In order to use the ECPSdkListener in your application, make your class implements ECPSdkListener. Additionally, pass the class which you would like to be a listener to the ECPSdk into the Initialize SDK method. You can also see Subscribe To Events for how to wire up additional listeners. See an example code block below for initialize:
public class LandingActivity extends AppCompatActivity implements ECPSdkListener {
////.....
exampleMethod() { // here is listener
_ecpSdk.initializeSdk(StripeLandingActivity.this, environment, tokenService, subscribedEvents, this, new InitializeSdkCallback() {
}
}
//.... more code here
// .....
// .....
// Later on down in your file, you can implement onDeviceEvent to listen to events coming in.
@Override
public void onDeviceEvent(ECPSdkEvent event) {
//code goes here to process each ECPSdkEvent coming in
}
}
ECPSdkListener
Property | Type | Description |
---|---|---|
void onDeviceEvent(ECPSdkEvent event) | Interface Method | Method which can be implemented to listen for device events related to the SDK. |
ECPSdkEvent Types
A generic type of event will be used as the base class for SDK events. This type is represented by a base class of ECPSdkEvent.
ECPSdkEvent
Property | Type | Description |
---|---|---|
message | String | Readable description of event. |
error | ECPEventError | Custom error object to help indicate any errors that may have occurred on ECPSdkEvent. |
ECPEventError
Custom error object used for error reporting within SDK.
Property | Type | Description |
---|---|---|
errorMessage | String | String containing error message description. |
Different subclasses of ECPSdkEvent will be utilized to represent different events. These classes are represented in the charts below.
ECPConnectionChangedEvent
Event that fires when a device connection status change is reported.
When a Stripe M2 reader is powered off, both an UNEXPECTED_DISCONNECT event and a NOT_CONNECTED event will fire. Ensure to handle this case in your app.
Property | Type | Description |
---|---|---|
status | enum (ECPConnectionStatus) | Indicates connection status of device. This enum can have the following potential enum values: UNKNOWN_STATUS, UNEXPECTED_DISCONNECT, NOT_CONNECTED, CONNECTING, CONNECTED |
ECPDeviceBatteryEvent
Event that fires when a battery event is reported.
Property | Type | Description |
---|---|---|
status | enum (ECPBatteryEventStatus) | Indicates type of battery event that took place. This enum can have the following potential enum values: BATTERY_LOW |
ECPDeviceCardEvent
Event that fires when a card is inserted or removed.
Property | Type | Description |
---|---|---|
eventStatus | enum (ECPCardEventStatus) | Indicates the type of device card event that took place. This enum can have the following potential values: UNKNOWN_EVENT, CARD_REMOVED, CARD_INSERTED |
ECPDeviceMessageEvent
Event that fires when a device prompts a user.
Property | Type | Description |
---|---|---|
inputOptions | Set Note - ECPInputOption is an enum, so the type above is a set of enum. | Indicates the type of input options the reader is prompting for. Also indicates the reader is waiting for input. ECPInputOption can have the following enum values: NONE, MANUAL_ENTRY, TAP, SWIPE, INSERT |
messageCode | enum (ECPDeviceMessageCode) | Indicates a message should be displayed to your user. ECPDeviceMessageCode can have the following enum values: NONE, CARD_REMOVED_TOO_EARLY, TRY_ANOTHER_CARD, TRY_ANOTHER_READ_METHOD, MULTIPLE_CONTACTLESS_CARDS_DETECTED, REMOVE_CARD, SWIPE_CARD, INSERT_OR_SWIPE_CARD, INSERT_CARD, RETRY_CARD, CHECK_MOBILE_DEVICE, INPUT_REQUESTED |
ECPDeviceConfigProgressEvent
Event that fires to report on config event progress.
Property | Type | Description |
---|---|---|
progress | float | Indicates the progress of a config event in the range of 0-1. |
ECPDeviceConfigStatusEvent
Event that fires when a config event takes place from a device. Note - on a config update event some readers may be unusable until required updates are completed.
Property | Type | Description |
---|---|---|
status | enum (ECPDeviceConfigStatus) | Indicates the type of config event that took place. This enum can have the following potential values: UNKNOWN, UPDATE_STARTING, UPDATE_IN_PROGRESS, UPDATE_FINISHED |
onDeviceEvent - Sample Implementation
This method will fire when an event is reported from the SDK, and the SDK consumer has chosen to subscribe in a particular file. See the code block below for sample implementation of listening and reporting on device events. Note - consumers are free to determine their own best practice for their particular use case to determine the type of ECPSdkEvent, below is just one example. Consumers can then utilize the specific event type that is known to exist and access event specific information to utilize in their application.
Important: If you are utilizing information in delegates to update UI, please follow best practices and dispatch UI changes to the main thread.
@Override
public void onDeviceEvent(ECPSdkEvent event) {
Log.i(TAG, "On Device Event triggered for event: " + event.message);
if (event instanceof ECPConnectionChangedEvent) {
ECPConnectionChangedEvent connectionChangedEvent = (ECPConnectionChangedEvent) event;
StringBuffer stringBuffer = new StringBuffer("ECPConnectionChangedEvent object details: ");
stringBuffer.append("\n" + "ECPConnectionChangedEvent Status: " + connectionChangedEvent.status);
stringBuffer.append("\n" + "ECPConnectionChangedEvent Message: " + connectionChangedEvent.message);
if(event.error != null) {
stringBuffer.append("\n" + "ECPConnectionChangedEvent Error present. Error message: " + event.error.errorMessage);
}
switch (connectionChangedEvent.status) {
case NOT_CONNECTED:
stringBuffer.append("\n" + "ConnectionChangedEvent - device not connected");
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(stringBuffer);
}
});
break;
case CONNECTING:
stringBuffer.append("\n" + "ConnectionChangedEvent - device connecting");
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(stringBuffer);
}
});
break;
case CONNECTED:
stringBuffer.append("\n" + "ConnectionChangedEvent - device connected");
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(stringBuffer);
}
});
break;
case UNEXPECTED_DISCONNECT:
stringBuffer.append("\n" + "ConnectionChangedEvent - unexpected disconnect");
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
responseView.setText(stringBuffer);
}
}, 1000);
break;
case UNKNOWN_STATUS:
stringBuffer.append("\n" + "ConnectionChangedEvent - unknown status");
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(stringBuffer);
}
});
break;
default:
break;
}
} else if (event instanceof ECPDeviceConfigStatusEvent) {
if (((ECPDeviceConfigStatusEvent) event).status == ECPDeviceConfigStatus.UPDATE_STARTING) {
if(event.error == null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(StripeLandingActivity.this, "Device has updates to install. Message: " + event.message, Toast.LENGTH_SHORT).show();
responseView.setText("Update starting...");
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(StripeLandingActivity.this, "ECPDeviceConfigStatusEvent update starting event has error. Error message: " + event.error.errorMessage , Toast.LENGTH_SHORT);
responseView.setText("Error object on ECPDeviceConfigStatusEvent with status of starting");
}
});
}
} else if (((ECPDeviceConfigStatusEvent) event).status == ECPDeviceConfigStatus.UPDATE_FINISHED) {
if(event.error == null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(StripeLandingActivity.this, "Device has finished updating. Message: " + event.message, Toast.LENGTH_SHORT).show();
responseView.setText("Update complete");
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(StripeLandingActivity.this, "ECPDeviceConfigStatusEvent update finished event has error. Error message: " + event.error.errorMessage, Toast.LENGTH_SHORT);
responseView.setText("Error object on ECPDeviceConfigStatusEvent with status of finished");
}
});
}
}
} else if (event instanceof ECPDeviceConfigProgressEvent) {
if(event.error == null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText("Update in progress: " + ((ECPDeviceConfigProgressEvent) event).progress);
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText("Error object on ECPDeviceConfigProgressEvent. Error message was: "
+ event.error.errorMessage);
}
});
}
} else if (event instanceof ECPDeviceMessageEvent) {
StringBuffer sb = new StringBuffer();
sb.append("Device Message: ").append(event.message);
sb.append("\nCode: ")
.append(((ECPDeviceMessageEvent) event).messageCode == null ? "null" : ((ECPDeviceMessageEvent) event).messageCode.toString());
Log.i(TAG, "message code: " + ((ECPDeviceMessageEvent) event).messageCode.toString());
if (((ECPDeviceMessageEvent) event).inputOptions != null) {
for (ECPInputOption option : ((ECPDeviceMessageEvent) event).inputOptions) {
Log.i(TAG, "Input option: " + option.toString());
sb.append("\nInput option: ").append(option);
}
}
if(event.error != null) {
sb.append("\nECPDeviceMessageEvent error present. Error message: " + event.error.errorMessage);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(sb.toString());
}
});
} else if (event instanceof ECPDeviceCardEvent) {
StringBuffer sb = new StringBuffer();
sb.append("Card Event: ").append(event.message);
sb.append("\nStatus: ")
.append(((ECPDeviceCardEvent) event).eventStatus == null ? "null" : ((ECPDeviceCardEvent) event).eventStatus.toString());
if (event.error != null) {
sb.append("\nECPDeviceCardEvent error present. Error message: " + event.error.errorMessage);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(sb.toString());
}
});
}
else if(event instanceof ECPDeviceBatteryEvent) {
ECPDeviceBatteryEvent batteryEvent = (ECPDeviceBatteryEvent) event;
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Battery Event object details: ");
stringBuffer.append("\n" + "ECPDeviceBatteryEvent Status: " + batteryEvent.status);
stringBuffer.append("\n" + "ECPDeviceBatteryEvent Message: " + batteryEvent.message);
if(event.error != null) {
stringBuffer.append("\n" + "ECPDeviceBatteryEvent Error present. Error message: " + batteryEvent.error.errorMessage);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
responseView.setText(stringBuffer);
}
});
}
}
Updated 9 months ago