├── flow-base-api
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── aevi
│ │ │ └── sdk
│ │ │ └── flow
│ │ │ ├── model
│ │ │ ├── DeviceAudience.java
│ │ │ ├── config
│ │ │ │ ├── FlowAppConditions.java
│ │ │ │ └── AppExecutionType.java
│ │ │ ├── Device.java
│ │ │ ├── BaseIdNameEntity.java
│ │ │ └── BaseModel.java
│ │ │ ├── constants
│ │ │ ├── InternalDataKeys.java
│ │ │ ├── ResponseMechanisms.java
│ │ │ ├── ServiceInfoErrors.java
│ │ │ ├── FlowServiceEventDataKeys.java
│ │ │ ├── AppMessageTypes.java
│ │ │ └── IntentActions.java
│ │ │ ├── util
│ │ │ └── ComparisonUtil.java
│ │ │ └── service
│ │ │ ├── BaseGenericService.java
│ │ │ ├── BaseStatusUpdateService.java
│ │ │ ├── BasePostGenericService.java
│ │ │ └── BaseResponseListenerService.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── flow
│ │ ├── ContextHelper.java
│ │ ├── service
│ │ └── BaseServiceInfoProviderTest.java
│ │ ├── TestHelper.java
│ │ └── model
│ │ └── FlowEventTest.java
└── build.gradle
├── sample-commons
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values
│ │ │ ├── bool.xml
│ │ │ ├── colors.xml
│ │ │ └── dimens.xml
│ │ ├── values-sw720dp
│ │ │ ├── bool.xml
│ │ │ └── dimens.xml
│ │ ├── color
│ │ │ └── item_button_text_color.xml
│ │ ├── drawable
│ │ │ ├── shadow_gradient.xml
│ │ │ ├── ic_code_black_24dp.xml
│ │ │ ├── ic_code_white_24dp.xml
│ │ │ ├── ic_description_black_24dp.xml
│ │ │ ├── ic_description_white_24dp.xml
│ │ │ ├── item_background.xml
│ │ │ ├── ic_help_outline_white_24dp.xml
│ │ │ ├── item_background_states.xml
│ │ │ └── flow_stage_selector.xml
│ │ ├── layout
│ │ │ ├── snippet_list_header.xml
│ │ │ ├── activity_model_details.xml
│ │ │ ├── fragment_model_details.xml
│ │ │ └── snippet_list_item.xml
│ │ └── menu
│ │ │ └── flow_menu.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── pos
│ │ └── flow
│ │ └── sample
│ │ ├── ui
│ │ ├── SectionHeaderViewHolder.java
│ │ ├── LabelValueViewHolder.java
│ │ ├── ModelDisplay.java
│ │ └── HelpActivity.java
│ │ ├── AmountFormatter.java
│ │ └── CustomerProducer.java
├── proguard-rules.pro
└── build.gradle
├── FlowServiceSample
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap
│ │ │ └── ic_launcher.png
│ │ ├── values-sw720dp
│ │ │ ├── styles.xml
│ │ │ └── strings.xml
│ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── integers.xml
│ │ │ └── styles.xml
│ │ ├── layout
│ │ │ ├── layout_split.xml
│ │ │ ├── layout_pre_flow.xml
│ │ │ ├── layout_pre_txn.xml
│ │ │ ├── view_pre_flow_fields.xml
│ │ │ ├── view_split_fields.xml
│ │ │ ├── activity_pre_txn.xml
│ │ │ └── activity_pre_flow.xml
│ │ └── layout-sw720dp
│ │ │ ├── layout_split.xml
│ │ │ ├── layout_pre_flow.xml
│ │ │ └── layout_pre_txn.xml
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── pos
│ │ └── flow
│ │ ├── stage
│ │ └── StageModelHelper.java
│ │ └── flowservicesample
│ │ ├── ui
│ │ ├── adapter
│ │ │ └── PaymentPropertiesAdapter.java
│ │ ├── PostCardActivity.java
│ │ └── PreTransactionActivity.java
│ │ └── service
│ │ └── PostGenericSampleService.java
├── proguard-rules.pro
└── build.gradle
├── PaymentServiceSample
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap
│ │ │ └── ic_launcher.png
│ │ ├── values-sw720dp
│ │ │ ├── styles.xml
│ │ │ └── strings.xml
│ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── array.xml
│ │ │ └── styles.xml
│ │ ├── layout
│ │ │ ├── layout_select_card.xml
│ │ │ ├── layout_payment_response.xml
│ │ │ ├── view_select_card_fields.xml
│ │ │ ├── view_payment_response_fields.xml
│ │ │ └── activity_select_card.xml
│ │ └── layout-sw720dp
│ │ │ ├── layout_select_card.xml
│ │ │ └── layout_payment_response.xml
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── pos
│ │ └── flow
│ │ └── paymentservicesample
│ │ └── util
│ │ ├── IdProvider.java
│ │ └── InMemoryStore.java
├── proguard-rules.pro
└── build.gradle
├── PaymentInitiationSample
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap
│ │ │ └── ic_launcher.png
│ │ ├── values-sw720dp
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ │ ├── values
│ │ │ ├── dimens.xml
│ │ │ ├── colors.xml
│ │ │ ├── styles.xml
│ │ │ └── array.xml
│ │ ├── layout
│ │ │ ├── snippet_checkbox.xml
│ │ │ ├── activity_popup.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── fragment_json_display.xml
│ │ │ ├── snippet_recycler_view_header.xml
│ │ │ ├── activity_payment.xml
│ │ │ ├── fragment_recycler_view.xml
│ │ │ ├── snippet_two_line_item_medium_title.xml
│ │ │ ├── snippet_event_info.xml
│ │ │ ├── snippet_two_line_item_large_title.xml
│ │ │ ├── snippet_result_line.xml
│ │ │ ├── activity_request.xml
│ │ │ ├── activity_generic_result.xml
│ │ │ ├── activity_payment_approved.xml
│ │ │ └── snippet_transaction.xml
│ │ ├── anim
│ │ │ ├── exit_to_left.xml
│ │ │ ├── exit_to_right.xml
│ │ │ ├── enter_from_left.xml
│ │ │ └── enter_from_right.xml
│ │ ├── drawable
│ │ │ ├── ic_close.xml
│ │ │ ├── ic_check_circle_amber.xml
│ │ │ ├── ic_check_circle.xml
│ │ │ ├── ic_question_answer.xml
│ │ │ ├── ic_error_circle.xml
│ │ │ └── ic_event.xml
│ │ └── layout-sw720dp
│ │ │ ├── activity_payment.xml
│ │ │ └── activity_request.xml
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── pos
│ │ └── flow
│ │ └── paymentinitiationsample
│ │ ├── ui
│ │ ├── MainActivity.java
│ │ ├── fragment
│ │ │ ├── BaseFragment.java
│ │ │ ├── SystemEventFragment.java
│ │ │ └── BaseItemFragment.java
│ │ └── adapter
│ │ │ ├── ApiFunctionsAdapter.java
│ │ │ ├── DevicesAdapter.java
│ │ │ └── FlowServicesAdapter.java
│ │ ├── model
│ │ ├── SystemEventHandler.java
│ │ ├── ApiFunction.java
│ │ └── SystemOverview.java
│ │ └── ConfirmationActionReceiver.java
├── proguard-rules.pro
└── build.gradle
├── payment-flow-service-api
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── aevi
│ │ │ └── sdk
│ │ │ └── pos
│ │ │ └── flow
│ │ │ └── PaymentFlowServiceApi.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── pos
│ │ └── flow
│ │ └── model
│ │ ├── FlowResponseTest.java
│ │ ├── TransactionResponseBuilderTest.java
│ │ ├── ContextHelper.java
│ │ └── CardBuilderTest.java
└── build.gradle
├── payment-initiation-api
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── aevi
│ │ │ └── sdk
│ │ │ └── pos
│ │ │ └── flow
│ │ │ ├── model
│ │ │ ├── RoundingStrategy.java
│ │ │ ├── events
│ │ │ │ ├── FinalAmountStatusType.java
│ │ │ │ ├── ProgressMessage.java
│ │ │ │ ├── NotifyAction.java
│ │ │ │ ├── FinalAmountRequest.java
│ │ │ │ └── ConfirmationOption.java
│ │ │ ├── Merchant.java
│ │ │ └── Measurement.java
│ │ │ └── service
│ │ │ └── BasePaymentResponseListenerService.java
│ └── test
│ │ ├── resources
│ │ └── error_response.json
│ │ └── java
│ │ └── com
│ │ └── aevi
│ │ └── sdk
│ │ └── pos
│ │ └── flow
│ │ ├── model
│ │ ├── events
│ │ │ ├── ReceiptTest.java
│ │ │ ├── ConfirmationRequestTest.java
│ │ │ └── FinalAmountRequestTest.java
│ │ ├── CardTest.java
│ │ ├── BasketItemModifierTest.java
│ │ └── BasketItemTest.java
│ │ ├── PaymentApiTest.java
│ │ └── ApiTestBase.java
└── build.gradle
├── publishLocally.sh
├── samples-key.jks
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── installSamples.sh
├── .idea
└── codeStyles
│ └── codeStyleConfig.xml
├── uninstallSamples.sh
├── .gitignore
├── settings.gradle
├── dist.gradle
├── .github
└── workflows
│ └── pr-build-test.yml
├── gradle.properties
└── CHANGELOG.md
/flow-base-api/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample-commons/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/FlowServiceSample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/PaymentServiceSample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/payment-flow-service-api/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/payment-initiation-api/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/publishLocally.sh:
--------------------------------------------------------------------------------
1 | ./gradlew jar publishApiJarPublicationToMavenLocal
2 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/samples-key.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AEVI-AppFlow/pos-android-sdk/HEAD/samples-key.jks
--------------------------------------------------------------------------------
/payment-flow-service-api/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AEVI-AppFlow/pos-android-sdk/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/sample-commons/src/main/res/values/bool.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/mipmap/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AEVI-AppFlow/pos-android-sdk/HEAD/FlowServiceSample/src/main/res/mipmap/ic_launcher.png
--------------------------------------------------------------------------------
/sample-commons/src/main/res/values-sw720dp/bool.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/mipmap/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AEVI-AppFlow/pos-android-sdk/HEAD/PaymentServiceSample/src/main/res/mipmap/ic_launcher.png
--------------------------------------------------------------------------------
/installSamples.sh:
--------------------------------------------------------------------------------
1 | ./gradlew :PaymentServiceSample:installRelease
2 | ./gradlew :FlowServiceSample:installRelease
3 | ./gradlew :PaymentInitiationSample:installRelease
4 |
5 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/mipmap/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AEVI-AppFlow/pos-android-sdk/HEAD/PaymentInitiationSample/src/main/res/mipmap/ic_launcher.png
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/values-sw720dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 40dp
4 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/uninstallSamples.sh:
--------------------------------------------------------------------------------
1 | adb uninstall com.aevi.sdk.pos.flow.paymentinitiationsample
2 | adb uninstall com.aevi.sdk.pos.flow.flowservicesample
3 | adb uninstall com.aevi.sdk.pos.flow.paymentservicesample
4 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/values-sw720dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/values-sw720dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/values-sw720dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | .externalNativeBuild
11 | documentation
12 | artifacts
13 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':payment-flow-service-api',
2 | ':flow-base-api',
3 | ':payment-initiation-api',
4 | ':sample-commons',
5 | ':PaymentInitiationSample',
6 | ':PaymentServiceSample',
7 | ':FlowServiceSample'
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #1b685b
5 | #737373
6 | #00688B
7 |
8 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3
4 | 50
5 | 500
6 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #b20000
5 | #737373
6 | #00688B
7 |
8 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jan 21 11:54:58 GMT 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
7 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8dp
4 | 8dp
5 | 20dp
6 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/color/item_button_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/shadow_gradient.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_checkbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/anim/exit_to_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/anim/exit_to_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/anim/enter_from_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/anim/enter_from_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
--------------------------------------------------------------------------------
/dist.gradle:
--------------------------------------------------------------------------------
1 | task publishJavadocsAsLatest(type: Exec, dependsOn: javadocs) {
2 | commandLine 'aws', '--region', 'eu-west-1', 's3', 'sync', 'documentation/public/javadocs', 's3://pos-flow-docs/javadocs/latest', '--acl', 'public-read'
3 | }
4 |
5 | task publishJavadocsByVersion(type: Exec, dependsOn: javadocs) {
6 | commandLine 'aws', '--region', 'eu-west-1', 's3', 'sync', 'documentation/public/javadocs', "s3://pos-flow-docs/javadocs/${rootProject.version}", '--acl', 'public-read'
7 | }
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/drawable/ic_close.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/drawable/ic_check_circle_amber.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/ic_code_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/ic_code_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/drawable/ic_check_circle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/activity_popup.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/drawable/ic_question_answer.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #00688B
5 | #737373
6 | #00688B
7 |
8 | #f1fff1
9 | #f1ffff
10 | #fff1f1
11 |
12 | #eeeeee
13 |
14 |
15 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/java/com/aevi/sdk/pos/flow/paymentservicesample/util/IdProvider.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.paymentservicesample.util;
2 |
3 | public final class IdProvider {
4 |
5 | private IdProvider() {
6 |
7 | }
8 |
9 | public static String getTerminalId() {
10 | return "12345678";
11 | }
12 |
13 | public static String getMerchantId() {
14 | return "87654321";
15 | }
16 |
17 | public static String getMerchantName() {
18 | return "Sample Merchant";
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/values-sw720dp/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Approve with token
5 | Payment Service Sample - Transaction processing step
6 | Payment Service Sample - Payment card reading step
7 | Payment Service Sample - Select token
8 | Payment Service Sample - Batch closure
9 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/RoundingStrategy.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 | /**
4 | * Strategies for rounding decimal numbers.
5 | */
6 | public enum RoundingStrategy {
7 | /**
8 | * Always round down. Both 15.2 and 15.9 is rounded to 15.
9 | */
10 | DOWN,
11 | /**
12 | * Round to nearest. 15.2 is rounded to 15, and 15.9 is rounded to 16.
13 | */
14 | NEAREST,
15 | /**
16 | * Always round up. Both 15.2 and 15.9 is rounded to 16.
17 | */
18 | UP
19 | }
20 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/drawable/ic_error_circle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/ic_description_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/ic_description_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/drawable/ic_event.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/layout_split.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/layout_pre_flow.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/layout_pre_txn.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/item_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/values/array.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - VISA
6 | - MASTERCARD
7 | - AMEX
8 |
9 |
10 |
11 | - card
12 | - cash
13 | - bitcoin
14 |
15 |
16 |
17 | - GBP
18 | - EUR
19 | - USD
20 |
21 |
22 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/resources/error_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "request": {
3 | "id": "d5766283-2853-4e0d-aa6a-e0d6999f9ed4",
4 | "amounts": {
5 | "base": {
6 | "value": 1000,
7 | "currency": "GBP"
8 | },
9 | "tip": {
10 | "value": 0,
11 | "currency": "GBP"
12 | },
13 | "other": {
14 | "value": 0,
15 | "currency": "GBP"
16 | }
17 | },
18 | "currency": "GBP",
19 | "type": "pay"
20 | },
21 | "transactions": [
22 | ],
23 | "options": {
24 | },
25 | "errorCode": "678",
26 | "status": "COMPLETE"
27 | }
28 |
29 |
30 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout/layout_select_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout/layout_payment_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/ic_help_outline_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/fragment_json_display.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/FlowServiceSample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/sample-commons/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/PaymentServiceSample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/model/DeviceAudience.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.model;
16 |
17 | /**
18 | * Represents the audience of a device.
19 | */
20 | public enum DeviceAudience {
21 | MERCHANT,
22 | CUSTOMER
23 | }
24 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/values-sw720dp/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Flow Service Sample - Pre-transaction
5 | Flow Service Sample - Loyalty Balance
6 | Flow Service Sample - Pre-flow
7 | Flow Service Sample - Post-transaction
8 | Flow Service Sample - Post-card-reading
9 | Flow Service Sample - Post-flow
10 | Flow Service Sample - Split
11 | Cancel payment
12 | Process split
13 | bypass split
14 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
12 |
13 |
17 |
18 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_recycler_view_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/values/array.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - tokenisation
6 | - reversal
7 | - receiptDelivery
8 | - showLoyaltyPointsBalance
9 | - basketStatusUpdate
10 | - batchClosure
11 |
12 |
13 |
14 | - @string/receipts_cash
15 | - @string/receipts_redeliver
16 |
17 |
18 |
19 | - 10.00
20 | - 10.00, tip: 5.00
21 | - 10.00, cashback: 5.00
22 | - 10.00, tip: 5.00, cashback: 2.50
23 | - 0.00
24 |
25 |
26 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/events/FinalAmountStatusType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.pos.flow.model.events;
15 |
16 | /**
17 | * Enum representing final amount response statuses
18 | */
19 | public enum FinalAmountStatusType {
20 | KNOWN,
21 | UNKNOWN,
22 | ABORT
23 | }
24 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/constants/InternalDataKeys.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.constants;
16 |
17 | /**
18 | * Keys for internal data.
19 | */
20 | public interface InternalDataKeys {
21 |
22 | String FLOW_STAGE = "flowStage";
23 | String FLOW_INITIATOR = "flowInitiator";
24 | }
25 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/layout/snippet_list_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
20 |
21 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/constants/ResponseMechanisms.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.constants;
16 |
17 | /**
18 | * Collection of supported response mechanism.
19 | */
20 | public interface ResponseMechanisms {
21 | String MESSENGER_CONNECTION = "messengerConnection";
22 | String RESPONSE_SERVICE = "responseService";
23 | }
24 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/model/config/FlowAppConditions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.model.config;
16 |
17 | /**
18 | * Conditions that can be associated with a flow app for it to be eligible to be called in a flow.
19 | */
20 | public interface FlowAppConditions {
21 |
22 | String OUTCOME_PARTIALLY_FULFILLED = "outcomePartiallyFulfilled";
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/model/events/ReceiptTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model.events;
2 |
3 | import com.aevi.sdk.flow.model.FlowEvent;
4 |
5 | import org.junit.Test;
6 |
7 | import static com.aevi.sdk.flow.constants.events.FlowEventTypes.EVENT_RECEIPT;
8 | import static org.assertj.core.api.Assertions.assertThat;
9 |
10 | public class ReceiptTest {
11 |
12 | @Test
13 | public void canSerialiseAsPayload() {
14 | String receiptText = "{ \"blah\": \"blah\" }";
15 | Receipt receipt = new Receipt("customer", receiptText);
16 | receipt.setReceiptData("json", receiptText);
17 | FlowEvent fe = new FlowEvent(EVENT_RECEIPT, receipt);
18 |
19 | String json = fe.toJson();
20 | System.out.println(json);
21 | FlowEvent result = FlowEvent.fromJson(json);
22 |
23 | Receipt resultData = result.getEventData(Receipt.class);
24 | assertThat(resultData).isEqualTo(receipt);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/values-sw720dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 40dp
6 | 16dp
7 | 4dp
8 | 6dp
9 | 6dp
10 |
11 | 25dp
12 |
13 | 22sp
14 | 200dp
15 | 3dp
16 |
17 | 300dp
18 | 3dp
19 | 30dp
20 | 18sp
21 | 0dp
22 | 50dp
23 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/model/CardTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | import static org.assertj.core.api.Java6Assertions.assertThat;
7 |
8 | public class CardTest {
9 |
10 | @Test(expected = IllegalArgumentException.class)
11 | public void shouldNotAllowPanWithMoreThan10Digits() throws Exception {
12 | new Card("1234567890123456", "Mr T", "0102", null, null);
13 | }
14 |
15 | @Test
16 | public void shouldAllowPanWithLessThan10Digits() throws Exception {
17 | Card card = new Card("123456789XXXXXX", "Mr T", "0102", null, null);
18 | assertThat(card.getMaskedPan()).isEqualTo("123456789XXXXXX");
19 | }
20 |
21 | @Test
22 | public void shouldFormatExpiryDateCorrectly() throws Exception {
23 | Card card = new Card("123456789XXXXXX", "Mr T", "2010", null, null);
24 | assertThat(card.getFormattedExpiryDate("MM/yyyy")).isEqualTo("10/2020");
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/sample-commons/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/payment-flow-service-api/src/test/java/com/aevi/sdk/pos/flow/model/FlowResponseTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | public class FlowResponseTest {
7 |
8 | @Test(expected = IllegalArgumentException.class)
9 | public void shouldNotAllowAmountsPaidLargerThanUpdatedAmounts() throws Exception {
10 | FlowResponse flowResponse = new FlowResponse();
11 |
12 | flowResponse.updateRequestAmounts(new Amounts(1000, "GBP"));
13 | flowResponse.setAmountsPaid(new Amounts(2000, "GBP"), "cash");
14 | flowResponse.validate();
15 | }
16 |
17 | @Test(expected = IllegalArgumentException.class)
18 | public void shouldNotAllowDifferentAmountCurrencies() throws Exception {
19 | FlowResponse flowResponse = new FlowResponse();
20 |
21 | flowResponse.setAmountsPaid(new Amounts(1000, "GBP"), "cash");
22 | flowResponse.updateRequestAmounts(new Amounts(1000, "EUR"));
23 | flowResponse.validate();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/pr-build-test.yml:
--------------------------------------------------------------------------------
1 | name: Build & Test Pull Requests
2 |
3 | env:
4 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
5 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
6 | GITHUB_ACTOR: ${{ secrets.CI_BOT_USERNAME }}
7 | GITHUB_TOKEN: ${{ secrets.CI_BOT_PAT }}
8 |
9 | on:
10 | pull_request:
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 |
20 | - name: Cache Gradle Dependencies
21 | uses: actions/cache@v2
22 | with:
23 | path: |
24 | ~/.gradle/caches
25 | ~/.gradle/wrapper
26 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
27 | restore-keys: |
28 | ${{ runner.os }}-gradle-
29 |
30 | - name: Set up JDK 11
31 | uses: actions/setup-java@v2
32 | with:
33 | distribution: zulu
34 | java-version: 11
35 |
36 | - name: Build
37 | run: ./gradlew build
38 |
--------------------------------------------------------------------------------
/payment-flow-service-api/src/test/java/com/aevi/sdk/pos/flow/model/TransactionResponseBuilderTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | import static org.assertj.core.api.Java6Assertions.assertThat;
7 |
8 | public class TransactionResponseBuilderTest {
9 |
10 | @Test(expected = IllegalArgumentException.class)
11 | public void shouldThrowIllegalArgumentIfIdNotSet() throws Exception {
12 | new TransactionResponseBuilder(null).approve().build();
13 | }
14 |
15 | @Test(expected = IllegalArgumentException.class)
16 | public void shouldThrowIllegalArgumentIfOutcomeNotSet() throws Exception {
17 | new TransactionResponseBuilder("1234").build();
18 | }
19 |
20 | @Test
21 | public void checkIsValid() {
22 | TransactionResponseBuilder trb = new TransactionResponseBuilder("1234");
23 |
24 | assertThat(trb.isValid()).isFalse();
25 |
26 | trb.approve();
27 |
28 | assertThat(trb.isValid()).isTrue();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #Thu, 09 Dec 2021 10:51:20 +0000
2 | # Project-wide Gradle settings.
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 | # For more details on how to configure your build environment visit
7 | # http://www.gradle.org/docs/current/userguide/build_environment.html
8 | # Specifies the JVM arguments used for the daemon process.
9 | # The setting is particularly useful for tweaking memory settings.
10 | org.gradle.jvmargs=-Xmx1536m
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | # App versioning - This is overridden by CI during builds based on tags
16 | android.useAndroidX=true
17 | android.enableJetifier=true
18 | version_major=2
19 | version_minor=4
20 | version_patch=0
21 | version_suffix=-SNAPSHOT
22 | version_build_counter=1
23 |
--------------------------------------------------------------------------------
/flow-base-api/src/test/java/com/aevi/sdk/flow/ContextHelper.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.flow;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.pm.PackageInfo;
6 | import android.content.pm.PackageManager;
7 |
8 | import static org.mockito.Matchers.anyInt;
9 | import static org.mockito.Matchers.anyString;
10 | import static org.mockito.Mockito.mock;
11 | import static org.mockito.Mockito.when;
12 |
13 | public class ContextHelper {
14 |
15 | public static Context mockContext(String packageName, String version) throws PackageManager.NameNotFoundException {
16 | Context context = mock(Context.class);
17 | PackageManager packageManager = mock(PackageManager.class);
18 | when(context.getPackageName()).thenReturn(packageName);
19 | when(context.getPackageManager()).thenReturn(packageManager);
20 | PackageInfo packageInfo = new PackageInfo();
21 | packageInfo.versionName = version;
22 | when(packageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo);
23 | return context;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/item_background_states.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
7 |
10 |
11 |
12 |
13 |
14 | -
15 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/view_pre_flow_fields.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
21 |
22 |
27 |
28 |
--------------------------------------------------------------------------------
/payment-flow-service-api/src/test/java/com/aevi/sdk/pos/flow/model/ContextHelper.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.pm.PackageInfo;
6 | import android.content.pm.PackageManager;
7 |
8 | import static org.mockito.Matchers.anyInt;
9 | import static org.mockito.Matchers.anyString;
10 | import static org.mockito.Mockito.mock;
11 | import static org.mockito.Mockito.when;
12 |
13 | public class ContextHelper {
14 |
15 | public static Context mockContext(String packageName, String version) throws PackageManager.NameNotFoundException {
16 | Context context = mock(Context.class);
17 | PackageManager packageManager = mock(PackageManager.class);
18 | when(context.getPackageName()).thenReturn(packageName);
19 | when(context.getPackageManager()).thenReturn(packageManager);
20 | PackageInfo packageInfo = new PackageInfo();
21 | packageInfo.versionName = version;
22 | when(packageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo);
23 | return context;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/activity_payment.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/constants/ServiceInfoErrors.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.flow.constants;
2 |
3 | /**
4 | * Error types related to {@link com.aevi.sdk.flow.service.BaseServiceInfoProvider#onServiceInfoError(String, String)}
5 | */
6 | public interface ServiceInfoErrors {
7 |
8 | /**
9 | * Indicates that the flow service did not return a service info response in time.
10 | *
11 | * The best approach to handling this is to call {@link com.aevi.sdk.flow.service.BaseServiceInfoProvider#notifyServiceInfoChange()} once all the required data
12 | * is cached in the application and can be returned without a need for network calls, etc.
13 | */
14 | String RETRIEVAL_TIME_OUT = "retrievalTimeOut";
15 |
16 | /**
17 | * Indicates that there were problems with how the flow service defines its stages.
18 | */
19 | String INVALID_STAGE_DEFINITIONS = "invalidStageDefinitions";
20 |
21 | /**
22 | * Indicates problems with the service info data reported from the flow service.
23 | */
24 | String INVALID_SERVICE_INFO = "invalidServiceInfo";
25 | }
26 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/menu/flow_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/Merchant.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.model;
16 |
17 | import com.aevi.sdk.flow.model.BaseIdNameEntity;
18 | import com.aevi.util.json.JsonConverter;
19 |
20 | /**
21 | * Represents a merchant.
22 | */
23 | public class Merchant extends BaseIdNameEntity {
24 |
25 | public Merchant(String id, String name) {
26 | super(id, name);
27 | }
28 |
29 | @Override
30 | public String toJson() {
31 | return JsonConverter.serialize(this);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/layout/activity_model_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui;
16 |
17 | import android.os.Bundle;
18 | import androidx.appcompat.app.AppCompatActivity;
19 | import com.aevi.sdk.pos.flow.paymentinitiationsample.R;
20 |
21 | public class MainActivity extends AppCompatActivity {
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_main);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/sample-commons/src/main/java/com/aevi/sdk/pos/flow/sample/ui/SectionHeaderViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.sample.ui;
16 |
17 |
18 | import androidx.recyclerview.widget.RecyclerView;
19 | import android.view.View;
20 | import android.widget.TextView;
21 | import com.aevi.sdk.pos.flow.sample.R;
22 |
23 | public class SectionHeaderViewHolder extends RecyclerView.ViewHolder {
24 |
25 | public final TextView title;
26 |
27 | public SectionHeaderViewHolder(View itemView) {
28 | super(itemView);
29 | title = itemView.findViewById(R.id.section_title);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/constants/FlowServiceEventDataKeys.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.constants;
16 |
17 | import com.aevi.sdk.flow.model.FlowEvent;
18 |
19 | /**
20 | * Data keys for flow service event data held in the {@link FlowEvent#getData()} structure.
21 | */
22 | public interface FlowServiceEventDataKeys {
23 |
24 | /**
25 | * In the case of a {@link FlowServiceEventTypes#RESPONSE_REJECTED} event, the reason for the rejection can be found via this data key.
26 | *
27 | * The reason is represented as a String.
28 | */
29 | String REJECTED_REASON = "rejectedReason";
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/model/Device.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.model;
16 |
17 |
18 | import com.aevi.util.json.JsonConverter;
19 |
20 | /**
21 | * Represents a device connected to the merchant device.
22 | */
23 | public class Device extends BaseIdNameEntity {
24 |
25 | public Device(String id, String name) {
26 | super(id, name);
27 | }
28 |
29 | @Override
30 | public String toJson() {
31 | return JsonConverter.serialize(this);
32 | }
33 |
34 | public static Device fromJson(String json) {
35 | return JsonConverter.deserialize(json, Device.class);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/java/com/aevi/sdk/pos/flow/stage/StageModelHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.stage;
16 |
17 | import com.aevi.sdk.pos.flow.model.FlowResponse;
18 |
19 | public class StageModelHelper {
20 |
21 | public static FlowResponse getFlowResponse(PreTransactionModel model) {
22 | return model.getFlowResponse();
23 | }
24 |
25 | public static FlowResponse getFlowResponse(PostTransactionModel model) {
26 | return model.getFlowResponse();
27 | }
28 |
29 | public static FlowResponse getFlowResponse(SplitModel model) {
30 | return model.getFlowResponse();
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/fragment_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
28 |
29 |
--------------------------------------------------------------------------------
/sample-commons/src/main/java/com/aevi/sdk/pos/flow/sample/ui/LabelValueViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.sample.ui;
16 |
17 |
18 | import androidx.recyclerview.widget.RecyclerView;
19 | import android.view.View;
20 | import android.widget.TextView;
21 | import com.aevi.sdk.pos.flow.sample.R;
22 |
23 | public class LabelValueViewHolder extends RecyclerView.ViewHolder {
24 |
25 | public final TextView label;
26 | public final TextView value;
27 |
28 | LabelValueViewHolder(View view) {
29 | super(view);
30 | label = view.findViewById(R.id.label);
31 | value = view.findViewById(R.id.value);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/PaymentApiTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow;
2 |
3 |
4 | import android.os.Build;
5 | import android.os.RemoteException;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import org.robolectric.RobolectricTestRunner;
9 | import org.robolectric.RuntimeEnvironment;
10 | import org.robolectric.annotation.Config;
11 |
12 | import static org.assertj.core.api.Java6Assertions.assertThat;
13 |
14 | import androidx.test.core.app.ApplicationProvider;
15 |
16 | @Config(manifest = Config.NONE)
17 | @RunWith(RobolectricTestRunner.class)
18 | public class PaymentApiTest extends ApiTestBase {
19 |
20 | public PaymentApiTest() {
21 | super("1.2.3");
22 | }
23 |
24 | @Test
25 | public void checkIsProcessingServiceInstalledReportsFalse() throws Exception {
26 | assertThat(PaymentApi.isProcessingServiceInstalled(ApplicationProvider.getApplicationContext())).isFalse();
27 | }
28 |
29 | @Test
30 | public void checkIsProcessingServiceInstalledFlagReportsTrue() throws RemoteException {
31 | setupMockBoundMessengerService();
32 |
33 | assertThat(PaymentApi.isProcessingServiceInstalled(ApplicationProvider.getApplicationContext())).isTrue();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout-sw720dp/layout_split.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout-sw720dp/layout_pre_flow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout-sw720dp/layout_pre_txn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/java/com/aevi/sdk/pos/flow/flowservicesample/ui/adapter/PaymentPropertiesAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.flowservicesample.ui.adapter;
16 |
17 |
18 | import android.content.Context;
19 | import com.aevi.sdk.pos.flow.model.Payment;
20 | import com.aevi.ui.library.recycler.LabelsListAdapter;
21 |
22 | public class PaymentPropertiesAdapter extends LabelsListAdapter {
23 |
24 | private Payment payment;
25 |
26 | public PaymentPropertiesAdapter(Context context, int labelsArrayRes) {
27 | super(context, labelsArrayRes);
28 | }
29 |
30 | @Override
31 | public void onBindViewHolder(ViewHolder viewHolder, int i) {
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ef5350
4 | #4b9b63
5 | #ffffff
6 |
7 | #ffcccccc
8 |
9 | #ffffff
10 | #4b9b63
11 | #3f8f50
12 | #dddddd
13 |
14 | #eeeeee
15 | #ffffff
16 |
17 | #eeeeee
18 | #ffcccccc
19 |
20 | #ffffff
21 | #9c9c9c
22 | #dddddd
23 |
24 | #ffffff
25 | #9c9c9c
26 | #d6e5d6
27 | #f8f8f8
28 |
--------------------------------------------------------------------------------
/payment-flow-service-api/src/main/java/com/aevi/sdk/pos/flow/PaymentFlowServiceApi.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow;
16 |
17 |
18 | import androidx.annotation.NonNull;
19 |
20 | import com.aevi.sdk.pos.flow.service.BuildConfig;
21 |
22 |
23 | /**
24 | * Provides general API information.
25 | */
26 | public final class PaymentFlowServiceApi {
27 |
28 | private PaymentFlowServiceApi() {
29 | }
30 |
31 | /**
32 | * Get the API version.
33 | *
34 | * The API versioning follows semver rules with major.minor.patch versions.
35 | *
36 | * @return The API version
37 | */
38 | @NonNull
39 | public static String getApiVersion() {
40 | return BuildConfig.VERSION;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout-sw720dp/layout_select_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/layout/fragment_model_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
24 |
25 |
29 |
30 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout-sw720dp/layout_payment_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/model/BasketItemModifierTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 | import org.junit.Test;
4 |
5 | public class BasketItemModifierTest {
6 |
7 | @Test(expected = IllegalArgumentException.class)
8 | public void shouldThrowExceptionIfNoName() throws Exception {
9 | new BasketItemModifier("bla", null, "type", 100f, 2.5f);
10 | }
11 |
12 | @Test(expected = IllegalArgumentException.class)
13 | public void shouldThrowExceptionIfNoType() throws Exception {
14 | new BasketItemModifier("bla", "name", null, 100f, 2.5f);
15 | }
16 |
17 | @Test(expected = IllegalArgumentException.class)
18 | public void shouldThrowExceptionIfNoAmountOrPercentage() throws Exception {
19 | new BasketItemModifier("bla", "name", "type", (Float)null, null);
20 | }
21 |
22 | @Test
23 | public void shouldAcceptJustAmount() throws Exception {
24 | new BasketItemModifier("bla", "name", "type", 100f, null);
25 | }
26 |
27 | @Test
28 | public void shouldAcceptJustPercentage() throws Exception {
29 | new BasketItemModifier("bla", "name", "type", (Float)null, 2.5f);
30 | }
31 |
32 | @Test
33 | public void shouldBuildFullInstance() throws Exception {
34 | new BasketItemModifier("bla", "name", "type", 100f, 2.5f);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/model/events/ConfirmationRequestTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model.events;
2 |
3 | import com.aevi.sdk.flow.model.FlowEvent;
4 |
5 | import org.junit.Test;
6 |
7 | import static com.aevi.sdk.flow.constants.events.FlowEventTypes.EVENT_CONFIRMATION_REQUEST;
8 | import static org.assertj.core.api.Assertions.assertThat;
9 |
10 | public class ConfirmationRequestTest {
11 |
12 | @Test
13 | public void canSerialiseAsPayload() {
14 | ConfirmationRequest confirmationRequest = new ConfirmationRequest("apple");
15 | confirmationRequest.setTitleText("Would you like a banana?");
16 | confirmationRequest.setConfirmationOptions(new ConfirmationOption[]{
17 | new ConfirmationOption("yes", "Yes please"),
18 | new ConfirmationOption("no", "No thanks")
19 | }, false);
20 | FlowEvent fe = new FlowEvent(EVENT_CONFIRMATION_REQUEST, confirmationRequest);
21 |
22 | String json = fe.toJson();
23 | System.out.println(json);
24 | FlowEvent result = FlowEvent.fromJson(json);
25 |
26 | ConfirmationRequest resultData = result.getEventData(ConfirmationRequest.class);
27 | assertThat(resultData).isEqualTo(confirmationRequest);
28 | assertThat(resultData.getConfirmationOptions()).hasSize(2);
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_two_line_item_medium_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
21 |
22 |
28 |
29 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/view_split_fields.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
17 |
18 |
23 |
24 |
29 |
30 |
35 |
36 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_event_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
24 |
25 |
32 |
33 |
--------------------------------------------------------------------------------
/flow-base-api/src/test/java/com/aevi/sdk/flow/service/BaseServiceInfoProviderTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.flow.service;
2 |
3 |
4 | import static org.assertj.core.api.Java6Assertions.assertThat;
5 | import static org.mockito.Mockito.verify;
6 |
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.os.Bundle;
10 |
11 | import org.junit.Test;
12 | import org.junit.runner.RunWith;
13 | import org.mockito.ArgumentCaptor;
14 | import org.robolectric.RobolectricTestRunner;
15 |
16 | @RunWith(RobolectricTestRunner.class)
17 | public class BaseServiceInfoProviderTest {
18 |
19 | private static final String SERVICE_INFO_STRING = "heeeelloooo";
20 |
21 | @Test
22 | public void shouldSetServiceInfoInBundleWithCorrectKey() throws Exception {
23 | TestServiceInfoProvider serviceInfoProvider = new TestServiceInfoProvider("");
24 | Bundle bundle = serviceInfoProvider.call("", "", null);
25 | assertThat(bundle.getString(BaseServiceInfoProvider.SERVICE_INFO_KEY)).isEqualTo(SERVICE_INFO_STRING);
26 | }
27 |
28 | class TestServiceInfoProvider extends BaseServiceInfoProvider {
29 |
30 | TestServiceInfoProvider(String serviceInfoChangeBroadcast) {
31 | super(serviceInfoChangeBroadcast);
32 | }
33 |
34 | @Override
35 | protected String getServiceInfo() {
36 | return SERVICE_INFO_STRING;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_two_line_item_large_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
20 |
21 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/service/BasePaymentResponseListenerService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.pos.flow.service;
15 |
16 | import com.aevi.sdk.flow.service.BaseListenerService;
17 | import com.aevi.sdk.pos.flow.initiation.BuildConfig;
18 | import com.aevi.sdk.pos.flow.model.PaymentResponse;
19 |
20 | /**
21 | * Extend this service in your application if you want to listen to payment responses initiated by your application,
22 | * or if you are implementing a flow service and want to listen to the final `PaymentResponse` when the flow is complete.
23 | */
24 | public abstract class BasePaymentResponseListenerService extends BaseListenerService {
25 |
26 | protected BasePaymentResponseListenerService() {
27 | super(PaymentResponse.class, BuildConfig.VERSION);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 12dp
4 | 20dp
5 | 12dp
6 | 4dp
7 | 6dp
8 | 6dp
9 |
10 | 25dp
11 |
12 | 22sp
13 | 200dp
14 | 3dp
15 |
16 | 150dp
17 | 2dp
18 | 20dp
19 | 10dp
20 | 30dp
21 | 50dp
22 | 50dp
23 | 80dp
24 | 110dp
25 | 10dp
26 |
27 | 5dp
28 | 5dp
29 | 12dp
30 | 16sp
31 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6 |
7 | ## [2.4.0] - TBD
8 |
9 | ### Changed
10 | - Updated all android/gradle build tools
11 | - Update to Androidx
12 | - Changed to build aar as the main archive output instead of jars
13 | - Fix up most/all dependencies
14 | - Fix up tests
15 | - Fix up javadcos and merged javadocs
16 |
17 | ## [2.2.8] - 2021-12-09
18 |
19 | ### Changed
20 | - Updated rxmessenger and config api to latest versions
21 |
22 | ## [2.2.7] - 2021-11-15
23 |
24 | ### Changed
25 | - Updated print api and json utils to latest versions hosted on GH repos
26 |
27 | ## [2.2.6] - 2021-03-04
28 |
29 | ### Fixed
30 | - Issue with FlowApp equals / hashCode not taking `delegateCancellationsTo` into account
31 |
32 | ## [2.2.5] - 2021-02-25
33 |
34 | ### Added
35 | - New flag `delegateCancellationsTo` for `FlowApp` to allow configuring cancellation delegations in the flow config
36 | - New flow service event `cancelOrResumeUserInterface`, that is sent to active flow services if the above flag is set and the merchant requests cancellation
37 |
38 | ## [2.2.4] - 2021-02-24
39 |
40 | First release with CHANGELOG, new CI workflows and publication to Github packages.
41 |
42 | Note that this release is functionally identical to v2.2.3.
--------------------------------------------------------------------------------
/sample-commons/src/main/res/layout/snippet_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
22 |
23 |
33 |
34 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/java/com/aevi/sdk/pos/flow/flowservicesample/service/PostGenericSampleService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.flowservicesample.service;
16 |
17 | import android.util.Log;
18 | import android.widget.Toast;
19 | import com.aevi.sdk.flow.service.BasePostGenericService;
20 | import com.aevi.sdk.flow.stage.PostGenericStageModel;
21 |
22 | public class PostGenericSampleService extends BasePostGenericService {
23 |
24 | @Override
25 | protected void processResponse(PostGenericStageModel stageModel) {
26 | Toast.makeText(this, "Received post-generic response data!", Toast.LENGTH_SHORT).show();
27 | Log.d(PostGenericSampleService.class.getSimpleName(), "processResponse: " + stageModel.getResponse().toJson());
28 | stageModel.addReferences("postGeneric", "wasHere");
29 | stageModel.sendResponse();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/java/com/aevi/sdk/pos/flow/paymentservicesample/util/InMemoryStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentservicesample.util;
16 |
17 |
18 | import com.aevi.sdk.pos.flow.model.TransactionResponse;
19 |
20 | public class InMemoryStore {
21 |
22 | private static final InMemoryStore INSTANCE = new InMemoryStore();
23 |
24 | public static InMemoryStore getInstance() {
25 | return INSTANCE;
26 | }
27 |
28 | private TransactionResponse lastTransactionResponseGenerated;
29 |
30 | public TransactionResponse getLastTransactionResponseGenerated() {
31 | return lastTransactionResponseGenerated;
32 | }
33 |
34 | public void setLastTransactionResponseGenerated(TransactionResponse lastTransactionResponseGenerated) {
35 | this.lastTransactionResponseGenerated = lastTransactionResponseGenerated;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/model/events/FinalAmountRequestTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model.events;
2 |
3 | import com.aevi.sdk.flow.model.FlowEvent;
4 | import com.aevi.sdk.pos.flow.model.Amounts;
5 |
6 | import org.junit.Test;
7 |
8 | import static com.aevi.sdk.flow.constants.events.FlowEventTypes.EVENT_FINAL_AMOUNT_REQUEST;
9 | import static org.assertj.core.api.Assertions.assertThat;
10 |
11 | public class FinalAmountRequestTest {
12 |
13 | @Test
14 | public void checkAmountsSet() {
15 | FinalAmountResponse finalAmount = new FinalAmountResponse(new Amounts(2772, "GBP"));
16 |
17 | assertThat(finalAmount.getAmounts().getBaseAmountValue()).isEqualTo(2772);
18 | assertThat(finalAmount.getAmounts().getCurrency()).isEqualTo("GBP");
19 | }
20 |
21 | @Test
22 | public void canSerialiseAsEventPayload() {
23 | FinalAmountResponse finalAmount = new FinalAmountResponse(new Amounts(1000, "GBP"));
24 | FlowEvent fe = new FlowEvent(EVENT_FINAL_AMOUNT_REQUEST, finalAmount);
25 |
26 | String json = fe.toJson();
27 | System.out.println(json);
28 | FlowEvent result = FlowEvent.fromJson(json);
29 |
30 | FinalAmountResponse resultFinalAmount = result.getEventData(FinalAmountResponse.class);
31 | assertThat(resultFinalAmount.getAmounts()).isEqualTo(finalAmount.getAmounts());
32 | assertThat(resultFinalAmount.getType()).isEqualTo(finalAmount.getType());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_result_line.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
23 |
24 |
33 |
34 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/constants/AppMessageTypes.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.constants;
16 |
17 | /**
18 | * Collection of message types used for communication between FPS and various apps.
19 | */
20 | public interface AppMessageTypes {
21 |
22 | // Initiated by client apps
23 | String REQUEST_MESSAGE = "request";
24 | String PAYMENT_MESSAGE = "payment";
25 | String PAYMENT_FLOW_CONFIG_REQUEST = "paymentFlowConfigRequest";
26 | String RESPONSES_REQUEST = "responsesRequest";
27 | String DEVICE_INFO_REQUEST = "deviceInfoRequest";
28 |
29 | // Sent from flow services
30 | String RESPONSE_MESSAGE = "response";
31 | String AUDIT_ENTRY = "auditEntry";
32 | String FAILURE_MESSAGE = "failure";
33 | String REQUEST_ACK_MESSAGE = "requestAck";
34 | String FLOW_EVENT = "flowEvent";
35 |
36 | // Sent by FPS
37 | String FLOW_SERVICE_EVENT = "flowServiceEvent";
38 | }
39 |
--------------------------------------------------------------------------------
/sample-commons/src/main/res/drawable/flow_stage_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
7 |
10 |
11 |
12 |
13 |
14 | -
15 |
17 |
20 |
21 |
22 |
23 |
24 | -
25 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/model/SystemEventHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.model;
16 |
17 | import android.util.Log;
18 | import com.aevi.sdk.flow.model.FlowEvent;
19 | import com.aevi.sdk.pos.flow.PaymentClient;
20 | import com.aevi.sdk.pos.flow.paymentinitiationsample.ui.adapter.SystemEventAdapter;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | public class SystemEventHandler {
26 |
27 | private final List receivedFlowEvents = new ArrayList<>();
28 |
29 | public void subscribeToEvents(PaymentClient paymentClient) {
30 | paymentClient.subscribeToSystemEvents()
31 | .subscribe(receivedFlowEvents::add,
32 | throwable -> Log.e(SystemEventAdapter.class.getSimpleName(), "Failed to subscribe", throwable));
33 | }
34 |
35 | public List getReceivedFlowEvents() {
36 | return receivedFlowEvents;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/model/ApiFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.model;
16 |
17 |
18 | public class ApiFunction {
19 |
20 | public enum ApiMethod {
21 | SYSTEM_OVERVIEW,
22 | DEVICES,
23 | FLOW_SERVICES,
24 | PAYMENT_RESPONSES,
25 | SUBSCRIBE_EVENTS,
26 | GENERIC_REQUEST,
27 | INITIATE_PAYMENT
28 | }
29 |
30 | private final ApiMethod apiMethod;
31 | private final String name;
32 | private final String description;
33 |
34 | public ApiFunction(ApiMethod apiMethod, String name, String description) {
35 | this.apiMethod = apiMethod;
36 | this.name = name;
37 | this.description = description;
38 | }
39 |
40 | public ApiMethod getApiMethod() {
41 | return apiMethod;
42 | }
43 |
44 | public String getName() {
45 | return name;
46 | }
47 |
48 | public String getDescription() {
49 | return description;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/util/ComparisonUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.util;
16 |
17 |
18 | import java.util.Collection;
19 |
20 | /**
21 | * Internal API comparison utilility.
22 | */
23 | public final class ComparisonUtil {
24 |
25 | private ComparisonUtil() {
26 | }
27 |
28 | public static boolean stringCollectionContainsIgnoreCase(Collection collection, String value) {
29 | if (value == null) {
30 | return false;
31 | }
32 | for (String entry : collection) {
33 | if (entry.equalsIgnoreCase(value)) {
34 | return true;
35 | }
36 | }
37 | return false;
38 | }
39 |
40 | public static boolean stringArrayContainsIgnoreCase(String[] array, String value) {
41 | if (value == null) {
42 | return false;
43 | }
44 | for (String arrayEntry : array) {
45 | if (arrayEntry.equalsIgnoreCase(value)) {
46 | return true;
47 | }
48 | }
49 | return false;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/payment-flow-service-api/src/test/java/com/aevi/sdk/pos/flow/model/CardBuilderTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | import static org.assertj.core.api.Java6Assertions.assertThat;
7 |
8 | public class CardBuilderTest {
9 |
10 | @Test
11 | public void canConstructCard() throws Exception {
12 | com.aevi.sdk.pos.flow.model.Card card = new com.aevi.sdk.pos.flow.model.CardBuilder()
13 | .withMaskedPan("1234 XXXX XXXX 5678")
14 | .withExpiryDate("1220")
15 | .withCardholderName("Mr T")
16 | .withCardToken(new com.aevi.sdk.flow.model.Token("abcdefgh12345678", "card", "blaha"))
17 | .withAdditionalData("blaha", "bluhu")
18 | .build();
19 | card.getCardToken().setSourceAppId("123");
20 |
21 | assertThat(card.getMaskedPan()).isEqualTo("1234 XXXX XXXX 5678");
22 | assertThat(card.getExpiryDate()).isEqualTo("1220");
23 | assertThat(card.getCardholderName()).isEqualTo("Mr T");
24 | assertThat(card.getCardToken().getValue()).isEqualTo("abcdefgh12345678");
25 | assertThat(card.getCardToken().getSource()).isEqualTo("card");
26 | assertThat(card.getCardToken().getAlgorithm()).isEqualTo("blaha");
27 | assertThat(card.getAdditionalData().getValue("blaha")).isEqualTo("bluhu");
28 | assertThat(card.getCardToken().getSourceAppId()).isEqualTo("123");
29 | }
30 |
31 | @Test
32 | public void shouldMaskPanCorrectly() throws Exception {
33 | String maskedPan = CardBuilder.maskPan("1234123412341234");
34 | assertThat(maskedPan).isEqualTo("123412XXXXXX1234");
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout/view_select_card_fields.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
24 |
25 |
30 |
31 |
36 |
37 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/sample-commons/src/main/java/com/aevi/sdk/pos/flow/sample/AmountFormatter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.sample;
16 |
17 | import java.math.BigDecimal;
18 | import java.util.Currency;
19 |
20 | public class AmountFormatter {
21 |
22 | /**
23 | * Format amount to a readable format, taking currency sub-unit fractions into account
24 | */
25 | public static String formatAmount(String currencyCode, long amountValue) {
26 | if (currencyCode != null) {
27 | String symbol;
28 | int subUnitFractions;
29 | try {
30 | Currency currency = Currency.getInstance(currencyCode);
31 | symbol = currency.getSymbol();
32 | subUnitFractions = currency.getDefaultFractionDigits();
33 | } catch (Throwable t) {
34 | symbol = currencyCode;
35 | subUnitFractions = 2;
36 | }
37 | return symbol + BigDecimal.valueOf(amountValue).movePointLeft(subUnitFractions).toString();
38 | } else {
39 | return "0.00";
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/sample-commons/src/main/java/com/aevi/sdk/pos/flow/sample/ui/ModelDisplay.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.sample.ui;
16 |
17 |
18 | import com.aevi.sdk.flow.model.AdditionalData;
19 | import com.aevi.sdk.flow.model.Request;
20 | import com.aevi.sdk.flow.model.Response;
21 | import com.aevi.sdk.pos.flow.model.*;
22 |
23 | public interface ModelDisplay {
24 |
25 | void showTitle(boolean show);
26 |
27 | void showPayment(Payment payment);
28 |
29 | void showRequest(Request request);
30 |
31 | void showTransactionRequest(TransactionRequest transactionRequest);
32 |
33 | void showSplitRequest(SplitRequest splitRequest);
34 |
35 | void showTransactionSummary(TransactionSummary transactionSummary);
36 |
37 | void showCard(Card card);
38 |
39 | void showTransactionResponse(TransactionResponse transactionResponse);
40 |
41 | void showPaymentResponse(PaymentResponse paymentResponse);
42 |
43 | void showResponse(Response response);
44 |
45 | void showFlowResponse(FlowResponse flowResponse);
46 |
47 | void showCustomData(AdditionalData additionalData);
48 | }
49 |
--------------------------------------------------------------------------------
/FlowServiceSample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | ext.applicationId = "com.aevi.sdk.pos.flow.flowservicesample"
4 | ext.applicationName = "FlowServiceSample"
5 |
6 | apply from: gradleScript('android/artifacts.gradle')
7 | apply from: gradleScript('android/versioning.gradle')
8 | apply from: gradleScript('android/basic-android.gradle')
9 |
10 | android {
11 | signingConfigs {
12 | release {
13 | storeFile file("../samples-key.jks")
14 | storePassword "appflow"
15 | keyAlias "sample"
16 | keyPassword "appflow"
17 | }
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | signingConfig signingConfigs.release
23 | }
24 | }
25 | lintOptions {
26 | abortOnError false
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(include: ['*.jar'], dir: 'libs')
32 | implementation(sampleDependencies.support) { force = true }
33 | implementation(sampleDependencies.appCompat) { force = true }
34 | implementation(sampleDependencies.recyclerView) { force = true }
35 | implementation(sampleDependencies.cardView) { force = true }
36 | implementation(sampleDependencies.design) { force = true }
37 | implementation apiDependencies.archLifecycle
38 | implementation apiDependencies.archLifecycleJava8
39 | implementation apiDependencies.rxJava
40 |
41 | implementation sampleDependencies.aeviUiLibrary
42 | implementation project(':payment-flow-service-api')
43 | implementation project(':sample-commons')
44 | implementation sampleDependencies.butterKnife
45 | annotationProcessor sampleAptDependencies.butterKnife
46 | }
47 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/fragment/BaseFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui.fragment;
16 |
17 | import androidx.recyclerview.widget.DividerItemDecoration;
18 | import androidx.recyclerview.widget.LinearLayoutManager;
19 | import androidx.recyclerview.widget.RecyclerView;
20 | import com.aevi.sdk.pos.flow.paymentinitiationsample.model.SampleContext;
21 | import com.aevi.ui.library.BaseObservableFragment;
22 |
23 | abstract class BaseFragment extends BaseObservableFragment {
24 |
25 | protected void setupRecyclerView(RecyclerView recyclerView) {
26 | LinearLayoutManager serviceInfoViewLayoutManager = new LinearLayoutManager(getContext());
27 | recyclerView.setLayoutManager(serviceInfoViewLayoutManager);
28 | DividerItemDecoration did = new DividerItemDecoration(recyclerView.getContext(), LinearLayoutManager.VERTICAL);
29 | recyclerView.addItemDecoration(did);
30 | }
31 |
32 | protected SampleContext getSampleContext() {
33 | return SampleContext.getInstance(getContext());
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/flow-base-api/src/test/java/com/aevi/sdk/flow/TestHelper.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.flow;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Intent;
5 | import android.content.IntentFilter;
6 | import android.content.pm.ApplicationInfo;
7 | import android.content.pm.PackageManager;
8 | import android.content.pm.ResolveInfo;
9 | import android.content.pm.ServiceInfo;
10 |
11 | import androidx.test.core.app.ApplicationProvider;
12 |
13 | import org.robolectric.RuntimeEnvironment;
14 | import org.robolectric.Shadows;
15 | import org.robolectric.shadow.api.Shadow;
16 | import org.robolectric.shadows.ShadowPackageManager;
17 |
18 | public class TestHelper {
19 |
20 | public static void pretendServiceIsInstalled(ComponentName componentName) {
21 | ShadowPackageManager packageManager = Shadows.shadowOf(ApplicationProvider.getApplicationContext().getPackageManager());
22 | Intent intent = new Intent();
23 | intent.setComponent(componentName);
24 |
25 | ResolveInfo resolveInfo = new ResolveInfo();
26 | resolveInfo.isDefault = true;
27 |
28 | ServiceInfo serviceInfo = new ServiceInfo();
29 | serviceInfo.packageName = componentName.getPackageName();
30 | ApplicationInfo applicationInfo = new ApplicationInfo();
31 | applicationInfo.packageName = serviceInfo.packageName;
32 | serviceInfo.applicationInfo = applicationInfo;
33 |
34 | resolveInfo.serviceInfo = serviceInfo;
35 |
36 | try {
37 | packageManager.addServiceIfNotPresent(componentName);
38 | packageManager.addIntentFilterForService(componentName, new IntentFilter());
39 | } catch (PackageManager.NameNotFoundException e) {
40 | e.printStackTrace();
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/sample-commons/src/main/java/com/aevi/sdk/pos/flow/sample/ui/HelpActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.sample.ui;
16 |
17 | import android.os.Bundle;
18 | import androidx.appcompat.app.AppCompatActivity;
19 | import android.view.Window;
20 | import android.widget.TextView;
21 | import com.aevi.sdk.pos.flow.sample.R;
22 |
23 | public class HelpActivity extends AppCompatActivity {
24 |
25 | public static final String KEY_TEXT = "text";
26 | public static final String KEY_TITLE_BG = "titleBgColor";
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
32 | setContentView(R.layout.activity_help);
33 |
34 | TextView helpText = findViewById(R.id.text);
35 | String text = getIntent().getStringExtra(KEY_TEXT);
36 | helpText.setText(text);
37 |
38 | int titleBg = getIntent().getIntExtra(KEY_TITLE_BG, 0);
39 | if (titleBg != 0) {
40 | TextView titleView = findViewById(R.id.title);
41 | titleView.setBackgroundColor(titleBg);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/adapter/ApiFunctionsAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui.adapter;
16 |
17 |
18 | import android.view.View;
19 | import com.aevi.sdk.pos.flow.paymentinitiationsample.R;
20 | import com.aevi.sdk.pos.flow.paymentinitiationsample.model.ApiFunction;
21 | import com.aevi.ui.library.recycler.BaseTwoLineAdapter;
22 |
23 | import java.util.List;
24 |
25 | public class ApiFunctionsAdapter extends BaseTwoLineAdapter {
26 |
27 | public ApiFunctionsAdapter(List items, OnItemSelectedListener listener, boolean withContextMenu) {
28 | super(items, listener, withContextMenu);
29 | }
30 |
31 | @Override
32 | protected int getSnippetResource() {
33 | return R.layout.snippet_two_line_item_large_title;
34 | }
35 |
36 | @Override
37 | protected void onBindViewHolderToObject(BaseTwoLineAdapter.ViewHolder holder, ApiFunction apiFunction, int i) {
38 | holder.title.setText(apiFunction.getName());
39 | holder.subtitle.setText(apiFunction.getDescription());
40 | holder.subtitle.setVisibility(View.VISIBLE);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/adapter/DevicesAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui.adapter;
16 |
17 |
18 | import android.view.View;
19 | import com.aevi.sdk.flow.model.Device;
20 | import com.aevi.sdk.pos.flow.paymentinitiationsample.R;
21 | import com.aevi.ui.library.recycler.AbstractListWithMenuAdapter;
22 | import com.aevi.ui.library.recycler.BaseTwoLineAdapter;
23 |
24 | import java.util.List;
25 |
26 |
27 | public class DevicesAdapter extends BaseTwoLineAdapter {
28 |
29 | public DevicesAdapter(List items, AbstractListWithMenuAdapter.OnItemSelectedListener listener, boolean withContextMenu) {
30 | super(items, listener, withContextMenu);
31 | }
32 |
33 | @Override
34 | protected int getSnippetResource() {
35 | return R.layout.snippet_two_line_item_medium_title;
36 | }
37 |
38 | @Override
39 | protected void onBindViewHolderToObject(BaseTwoLineAdapter.ViewHolder holder, Device device, int i) {
40 | holder.title.setText(device.getName());
41 | holder.subtitle.setText(device.getId());
42 | holder.subtitle.setVisibility(View.VISIBLE);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout-sw720dp/activity_payment.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
20 |
21 |
28 |
29 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | ext.applicationId = "com.aevi.sdk.pos.flow.paymentinitiationsample"
4 | ext.applicationName = "PaymentInitiationSample"
5 |
6 | apply from: gradleScript('android/artifacts.gradle')
7 | apply from: gradleScript('android/versioning.gradle')
8 | apply from: gradleScript('android/basic-android.gradle')
9 |
10 | android {
11 | signingConfigs {
12 | release {
13 | storeFile file("../samples-key.jks")
14 | storePassword "appflow"
15 | keyAlias "sample"
16 | keyPassword "appflow"
17 | }
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | signingConfig signingConfigs.release
23 | }
24 | }
25 | lintOptions {
26 | abortOnError false
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(dir: 'libs', include: ['*.jar'])
32 |
33 | implementation project(':payment-initiation-api')
34 | implementation project(':sample-commons')
35 | implementation apiDependencies.archLifecycle
36 | implementation apiDependencies.archLifecycleJava8
37 | implementation apiDependencies.rxJava
38 | implementation apiDependencies.rxAndroid
39 | implementation apiDependencies.gson
40 | implementation sampleDependencies.aeviUiLibrary
41 |
42 | implementation(sampleDependencies.support) { force = true }
43 | implementation(sampleDependencies.appCompat) { force = true }
44 | implementation(sampleDependencies.recyclerView) { force = true }
45 | implementation(sampleDependencies.cardView) { force = true }
46 | implementation(sampleDependencies.design) { force = true }
47 |
48 | implementation sampleDependencies.butterKnife
49 | annotationProcessor sampleAptDependencies.butterKnife
50 | }
51 |
--------------------------------------------------------------------------------
/PaymentServiceSample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | ext.applicationId = "com.aevi.sdk.pos.flow.paymentservicesample"
4 | ext.applicationName = "PaymentServiceSample"
5 |
6 | apply from: gradleScript('android/artifacts.gradle')
7 | apply from: gradleScript('android/versioning.gradle')
8 | apply from: gradleScript('android/basic-android.gradle')
9 |
10 | android {
11 | signingConfigs {
12 | release {
13 | storeFile file("../samples-key.jks")
14 | storePassword "appflow"
15 | keyAlias "sample"
16 | keyPassword "appflow"
17 | }
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | signingConfig signingConfigs.release
23 | }
24 | }
25 | lintOptions {
26 | abortOnError false
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(include: ['*.jar'], dir: 'libs')
32 | implementation(sampleDependencies.support) { force = true }
33 | implementation(sampleDependencies.appCompat) { force = true }
34 | implementation(sampleDependencies.recyclerView) { force = true }
35 | implementation(sampleDependencies.cardView) { force = true }
36 | implementation(sampleDependencies.design) { force = true }
37 | implementation apiDependencies.archLifecycle
38 | implementation apiDependencies.archLifecycleJava8
39 | implementation apiDependencies.rxAndroid
40 | implementation apiDependencies.rxJava
41 | implementation sampleDependencies.aeviUiLibrary
42 | implementation project(':payment-flow-service-api')
43 | implementation sampleDependencies.appFlowConstants
44 | implementation project(':sample-commons')
45 | implementation sampleDependencies.butterKnife
46 |
47 | annotationProcessor sampleAptDependencies.butterKnife
48 | }
49 |
--------------------------------------------------------------------------------
/sample-commons/src/main/java/com/aevi/sdk/pos/flow/sample/CustomerProducer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.sample;
16 |
17 | import com.aevi.sdk.flow.constants.CustomerDataKeys;
18 | import com.aevi.sdk.flow.model.Customer;
19 | import com.aevi.sdk.flow.model.Token;
20 |
21 | import java.util.UUID;
22 |
23 | public class CustomerProducer {
24 |
25 | private static final String CUSTOMER_ID = UUID.randomUUID().toString();
26 | private static final String CUSTOMER_NAME = "Joanna Doe";
27 | private static final String CUSTOMER_EMAIL = "joanna@doe.com";
28 | private static final String CUSTOMER_PHONE = "12345678";
29 |
30 | public static final Token CUSTOMER_TOKEN = new Token(UUID.randomUUID().toString(), "card", "random");
31 |
32 | public static Customer getDefaultCustomer(String source) {
33 | Customer customer = new Customer(CUSTOMER_ID);
34 | customer.setFullName(CUSTOMER_NAME);
35 | customer.addCustomerDetails(CustomerDataKeys.EMAIL, CUSTOMER_EMAIL);
36 | customer.addCustomerDetails(CustomerDataKeys.PHONE, CUSTOMER_PHONE);
37 | customer.addCustomerDetails("generatedBy", source);
38 | customer.addToken(CUSTOMER_TOKEN);
39 | return customer;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/java/com/aevi/sdk/pos/flow/flowservicesample/ui/PostCardActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.flowservicesample.ui;
16 |
17 | import android.os.Bundle;
18 | import androidx.appcompat.widget.Toolbar;
19 | import butterknife.BindView;
20 | import com.aevi.sdk.flow.constants.FlowStages;
21 | import com.aevi.sdk.pos.flow.flowservicesample.R;
22 |
23 | /**
24 | * Sample activity for post-card-reading stage. See base class.
25 | *
26 | * This sample illustrates the data made available to the flow application at these stages,
27 | * and in what different ways a post-card-reading flow app can augment the transaction.
28 | */
29 | public class PostCardActivity extends BasePreProcessingActivity {
30 |
31 | @BindView(R.id.toolbar)
32 | Toolbar toolbar;
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setupToolbar(toolbar, R.string.fss_post_card);
38 | }
39 |
40 | @Override
41 | protected String getCurrentStage() {
42 | return FlowStages.POST_CARD_READING;
43 | }
44 |
45 | @Override
46 | protected String getHelpText() {
47 | return getString(R.string.post_card_reading_help);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/adapter/FlowServicesAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui.adapter;
16 |
17 |
18 | import android.view.View;
19 | import com.aevi.sdk.pos.flow.model.PaymentFlowServiceInfo;
20 | import com.aevi.sdk.pos.flow.paymentinitiationsample.R;
21 | import com.aevi.ui.library.recycler.BaseTwoLineAdapter;
22 |
23 | import java.util.List;
24 |
25 | public class FlowServicesAdapter extends BaseTwoLineAdapter {
26 |
27 | public FlowServicesAdapter(List items, OnItemSelectedListener listener, boolean withContextMenu) {
28 | super(items, listener, withContextMenu);
29 | }
30 |
31 | @Override
32 | protected int getSnippetResource() {
33 | return R.layout.snippet_two_line_item_medium_title;
34 | }
35 |
36 | @Override
37 | protected void onBindViewHolderToObject(BaseTwoLineAdapter.ViewHolder holder, PaymentFlowServiceInfo paymentFlowServiceInfo, int i) {
38 | holder.title.setText(paymentFlowServiceInfo.getDisplayName());
39 | holder.subtitle.setText(paymentFlowServiceInfo.getVendor());
40 | holder.subtitle.setVisibility(View.VISIBLE);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/events/ProgressMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.pos.flow.model.events;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | import java.util.Objects;
19 |
20 | /**
21 | * A simple message event
22 | */
23 | public class ProgressMessage {
24 |
25 | @NonNull
26 | private final String messageText;
27 |
28 | public ProgressMessage(@NonNull String messageText) {
29 | this.messageText = messageText;
30 | }
31 |
32 | /**
33 | * @return The message
34 | */
35 | @NonNull
36 | public String getMessageText() {
37 | return messageText;
38 | }
39 |
40 | @Override
41 | public boolean equals(Object o) {
42 | if (this == o) return true;
43 | if (o == null || getClass() != o.getClass()) return false;
44 | ProgressMessage that = (ProgressMessage) o;
45 | return messageText.equals(that.messageText);
46 | }
47 |
48 | @Override
49 | public int hashCode() {
50 | return Objects.hash(messageText);
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return "ProgressMessage{" +
56 | "messageText='" + messageText + '\'' +
57 | '}';
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/events/NotifyAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.pos.flow.model.events;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | import java.util.Objects;
19 |
20 | /**
21 | * A general purpose event indicating something has happened or the notification of some event
22 | */
23 | public class NotifyAction {
24 |
25 | @NonNull
26 | private final String type;
27 |
28 | public NotifyAction(@NonNull String type) {
29 | this.type = type;
30 | }
31 |
32 | /**
33 | * @return What type of notification event this is
34 | */
35 | @NonNull
36 | public String getType() {
37 | return type;
38 | }
39 |
40 | @Override
41 | public boolean equals(Object o) {
42 | if (this == o) return true;
43 | if (o == null || getClass() != o.getClass()) return false;
44 | NotifyAction that = (NotifyAction) o;
45 | return type.equals(that.type);
46 | }
47 |
48 | @Override
49 | public int hashCode() {
50 | return Objects.hash(type);
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return "NotifyAction{" +
56 | "type='" + type + '\'' +
57 | '}';
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/sample-commons/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | apply from: gradleScript('android/versioning.gradle')
4 |
5 | android {
6 | compileSdkVersion applicationTargetSdkVersion
7 |
8 | defaultConfig {
9 | minSdkVersion applicationMinSdkVersion
10 | targetSdkVersion applicationTargetSdkVersion
11 | versionCode applicationVersionCode
12 | versionName applicationVersionName
13 | }
14 |
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | lintOptions {
22 | abortOnError false
23 | }
24 |
25 | compileOptions {
26 | sourceCompatibility JavaVersion.VERSION_1_8
27 | targetCompatibility JavaVersion.VERSION_1_8
28 | }
29 |
30 | testOptions {
31 | unitTests.returnDefaultValues = true
32 | }
33 | }
34 |
35 | dependencies {
36 | implementation fileTree(dir: 'libs', include: ['*.jar'])
37 |
38 | api sampleDependencies.appFlowConstants
39 |
40 | implementation apiDependencies.gson
41 |
42 | implementation(sampleDependencies.support) { force = true }
43 | implementation(sampleDependencies.appCompat) { force = true }
44 | implementation(sampleDependencies.recyclerView) { force = true }
45 | implementation(sampleDependencies.cardView) { force = true }
46 | implementation(sampleDependencies.design) { force = true }
47 |
48 | implementation project(':payment-initiation-api')
49 | implementation project(':payment-flow-service-api')
50 | implementation sampleDependencies.aeviUiLibrary
51 | implementation 'com.github.luizgrp:sectionedrecyclerviewadapter:1.2.0'
52 |
53 | testImplementation testDependencies.junit
54 | testImplementation testDependencies.mockito
55 | testImplementation testDependencies.assertJ
56 | }
57 |
--------------------------------------------------------------------------------
/payment-flow-service-api/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | apply from: gradleScript('lib/versioning.gradle')
4 | apply from: gradleScript('android/versioning.gradle')
5 | apply from: gradleScript('publish/publishing-utils.gradle')
6 | apply from: gradleScript('android/basic-library.gradle')
7 |
8 | group = 'com.aevi.sdk.pos.flow'
9 | version = libraryVersion
10 | description = 'payment-flow-service-api'
11 |
12 | publishingUtils?.publication {
13 | groupId group
14 | artifactId project.name
15 | version libraryVersion
16 | }
17 |
18 | apply from: gradleScript('publish/publish-maven-central.gradle')
19 |
20 | android {
21 | defaultConfig {
22 | buildConfigField("String", "NAME", "\"${project.name}\"")
23 | buildConfigField("String", "VERSION", "\"${libraryVersion}\"")
24 | buildConfigField("long", "BUILD_TIME", "${System.currentTimeMillis()}L")
25 | }
26 | }
27 |
28 | dependencies {
29 | api project(':payment-initiation-api')
30 | api project(':flow-base-api')
31 |
32 | implementation apiDependencies.gson
33 | implementation apiDependencies.rxJava
34 | implementation apiDependencies.rxMessenger
35 | implementation apiDependencies.jsonConverter
36 |
37 | testImplementation testDependencies.junit
38 | testImplementation testDependencies.mockito
39 | testImplementation testDependencies.assertJ
40 | }
41 |
42 | task androidJavadocs(type: Javadoc) {
43 | source = android.sourceSets.main.java.sourceFiles
44 | source += fileTree(dir: "$buildDir/generated/source/buildConfig/release/")
45 | classpath += files(android.getBootClasspath())
46 | android.libraryVariants.all { variant ->
47 | if (variant.name == 'release') {
48 | owner.classpath += variant.javaCompileProvider.get().classpath
49 | }
50 | }
51 |
52 | title "Flow Service API"
53 | options.memberLevel = JavadocMemberLevel.PUBLIC
54 | failOnError false
55 | }
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/service/BaseGenericService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.service;
16 |
17 |
18 | import androidx.annotation.NonNull;
19 | import androidx.annotation.Nullable;
20 |
21 | import com.aevi.sdk.flow.BuildConfig;
22 | import com.aevi.sdk.flow.model.InternalData;
23 | import com.aevi.sdk.flow.model.Request;
24 | import com.aevi.sdk.flow.stage.GenericStageModel;
25 |
26 | /**
27 | * Base service for handling generic requests defined by a request type and associated bespoke data.
28 | */
29 | public abstract class BaseGenericService extends BaseApiService {
30 |
31 | public BaseGenericService() {
32 | super(BuildConfig.VERSION);
33 | }
34 |
35 | @Override
36 | protected final void processRequest(@NonNull ClientCommunicator clientCommunicator, @NonNull String request,
37 | @Nullable InternalData senderInternalData) {
38 | GenericStageModel genericStageModel = GenericStageModel.fromService(clientCommunicator, Request.fromJson(request), senderInternalData);
39 | processRequest(genericStageModel);
40 | }
41 |
42 | /**
43 | * Handle the generic request.
44 | *
45 | * @param stageModel The generic stage model
46 | */
47 | protected abstract void processRequest(@NonNull GenericStageModel stageModel);
48 | }
49 |
--------------------------------------------------------------------------------
/flow-base-api/src/test/java/com/aevi/sdk/flow/model/FlowEventTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.flow.model;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 |
6 | import java.util.Objects;
7 |
8 | import static org.assertj.core.api.Java6Assertions.assertThat;
9 |
10 | public class FlowEventTest {
11 |
12 |
13 | @Before
14 | public void setUp() throws Exception {
15 | }
16 |
17 | @Test
18 | public void canSerialise() {
19 | FlowEvent fe = new FlowEvent("blah");
20 |
21 | String json = fe.toJson();
22 |
23 | FlowEvent result = FlowEvent.fromJson(json);
24 |
25 | assertThat(fe).isEqualTo(result);
26 | }
27 |
28 | @Test
29 | public void canSetAndGetDomainEventData() {
30 | TestEventObjectData data = new TestEventObjectData();
31 | FlowEvent fe = new FlowEvent("blah", data);
32 |
33 | assertThat(fe.getEventData(TestEventObjectData.class)).isNotNull();
34 | assertThat(fe.getEventData(TestEventObjectData.class)).isEqualTo(data);
35 | }
36 |
37 | @Test
38 | public void shouldReturnNullIfWrongTypeUsed() {
39 | TestEventObjectData data = new TestEventObjectData();
40 | FlowEvent fe = new FlowEvent("blah", data);
41 |
42 | assertThat(fe.getEventData(FlowEvent.class)).isNull();
43 | }
44 |
45 | class TestEventObjectData {
46 | String banana = "Woo";
47 | int apple = 10;
48 |
49 | @Override
50 | public boolean equals(Object o) {
51 | if (this == o) return true;
52 | if (o == null || getClass() != o.getClass()) return false;
53 | TestEventObjectData that = (TestEventObjectData) o;
54 | return apple == that.apple &&
55 | Objects.equals(banana, that.banana);
56 | }
57 |
58 | @Override
59 | public int hashCode() {
60 | return Objects.hash(banana, apple);
61 | }
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/activity_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
19 |
20 |
26 |
27 |
28 |
29 |
36 |
37 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/Measurement.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 | import java.util.Objects;
4 |
5 | import static com.aevi.sdk.flow.util.Preconditions.checkNotEmpty;
6 |
7 | /**
8 | * Represents a measurement with a value and unit.
9 | *
10 | * Examples are "2.5 kilograms" or "13.45 feet".
11 | */
12 | public class Measurement {
13 |
14 | private final float value;
15 | private final String unit;
16 |
17 | /**
18 | * Create a new measurement.
19 | *
20 | * @param value The value
21 | * @param unit The unit
22 | */
23 | public Measurement(float value, String unit) {
24 | checkNotEmpty(unit, "Unit must be set for measurement");
25 | this.value = value;
26 | this.unit = unit;
27 | }
28 |
29 | /**
30 | * Get the value of this measurement.
31 | *
32 | * @return The value of this measurement
33 | */
34 | public float getValue() {
35 | return value;
36 | }
37 |
38 | /**
39 | * Get the unit of this measurement.
40 | *
41 | * @return The unit of this measurement
42 | */
43 | public String getUnit() {
44 | return unit;
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | return "Measurement{" +
50 | "value=" + value +
51 | ", unit='" + unit + '\'' +
52 | '}';
53 | }
54 |
55 | @Override
56 | public boolean equals(Object o) {
57 | if (this == o) {
58 | return true;
59 | }
60 | if (o == null || getClass() != o.getClass()) {
61 | return false;
62 | }
63 | Measurement that = (Measurement) o;
64 | return Float.compare(that.value, value) == 0 &&
65 | Objects.equals(unit, that.unit);
66 | }
67 |
68 | @Override
69 | public int hashCode() {
70 | return Objects.hash(value, unit);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/service/BaseStatusUpdateService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.service;
16 |
17 | import androidx.annotation.NonNull;
18 | import androidx.annotation.Nullable;
19 |
20 | import com.aevi.sdk.flow.BuildConfig;
21 | import com.aevi.sdk.flow.model.InternalData;
22 | import com.aevi.sdk.flow.model.Request;
23 | import com.aevi.sdk.flow.stage.StatusUpdateModel;
24 |
25 | /**
26 | * Base service for handling status update requests defined by a request type and associated bespoke data.
27 | */
28 | public abstract class BaseStatusUpdateService extends BaseApiService {
29 |
30 | public BaseStatusUpdateService() {
31 | super(BuildConfig.VERSION);
32 | }
33 |
34 | @Override
35 | protected final void processRequest(@NonNull ClientCommunicator clientCommunicator, @NonNull String request,
36 | @Nullable InternalData senderInternalData) {
37 | StatusUpdateModel statusUpdateModel = StatusUpdateModel.fromService(clientCommunicator, Request.fromJson(request), senderInternalData);
38 | processRequest(statusUpdateModel);
39 | }
40 |
41 | /**
42 | * Handle the status update request.
43 | *
44 | * @param stageModel The status update stage model
45 | */
46 | protected abstract void processRequest(@NonNull StatusUpdateModel stageModel);
47 | }
48 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/service/BasePostGenericService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.service;
16 |
17 | import androidx.annotation.NonNull;
18 | import androidx.annotation.Nullable;
19 |
20 | import com.aevi.sdk.flow.BuildConfig;
21 | import com.aevi.sdk.flow.model.InternalData;
22 | import com.aevi.sdk.flow.model.Response;
23 | import com.aevi.sdk.flow.stage.PostGenericStageModel;
24 |
25 | /**
26 | * Base service for handling post-generic stages which receive the response from the main generic stage.
27 | */
28 | public abstract class BasePostGenericService extends BaseApiService {
29 |
30 | protected BasePostGenericService() {
31 | super(BuildConfig.VERSION);
32 | }
33 |
34 | @Override
35 | protected final void processRequest(@NonNull ClientCommunicator clientCommunicator, @NonNull String request,
36 | @Nullable InternalData senderInternalData) {
37 | PostGenericStageModel postGenericStageModel =
38 | PostGenericStageModel.fromService(clientCommunicator, Response.fromJson(request), senderInternalData);
39 | processResponse(postGenericStageModel);
40 | }
41 |
42 | /**
43 | * Handle the generic response.
44 | *
45 | * @param stageModel The post-generic stage model
46 | */
47 | protected abstract void processResponse(@NonNull PostGenericStageModel stageModel);
48 | }
49 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/activity_generic_result.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
33 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout/view_payment_response_fields.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
20 |
21 |
26 |
27 |
30 |
31 |
38 |
39 |
43 |
44 |
49 |
50 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/java/com/aevi/sdk/pos/flow/flowservicesample/ui/PreTransactionActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.flowservicesample.ui;
16 |
17 | import android.os.Bundle;
18 | import androidx.appcompat.widget.Toolbar;
19 | import butterknife.BindView;
20 | import com.aevi.sdk.flow.constants.FlowStages;
21 | import com.aevi.sdk.pos.flow.flowservicesample.R;
22 | import com.aevi.sdk.pos.flow.stage.PreTransactionModel;
23 |
24 | /**
25 | * Sample activity for pre-payment stage. See base class.
26 | *
27 | * This sample illustrates the data made available to the flow application at these stages,
28 | * and in what different ways a pre-payment flow app can augment the transaction.
29 | */
30 | public class PreTransactionActivity extends BasePreProcessingActivity {
31 |
32 | @BindView(R.id.toolbar)
33 | Toolbar toolbar;
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | setupToolbar(toolbar, R.string.fss_pre_payment);
39 | PreTransactionModel preTransactionModel = PreTransactionModel.fromActivity(this);
40 | sendClientMessage(preTransactionModel, R.string.message_pre_transaction);
41 | }
42 |
43 | @Override
44 | protected String getCurrentStage() {
45 | return FlowStages.PRE_TRANSACTION;
46 | }
47 |
48 | @Override
49 | protected String getHelpText() {
50 | return getString(R.string.pre_txn_help);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/activity_pre_txn.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
25 |
26 |
38 |
39 |
40 |
46 |
47 |
--------------------------------------------------------------------------------
/FlowServiceSample/src/main/res/layout/activity_pre_flow.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
25 |
26 |
38 |
39 |
40 |
46 |
47 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/model/config/AppExecutionType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.model.config;
16 |
17 | /**
18 | * Represents the selection strategy for flow apps in a particular flow stage.
19 | */
20 | public enum AppExecutionType {
21 |
22 | /**
23 | * Only a single application (the first, if there are multiple in the list) will be executed, without any operator interaction.
24 | *
25 | * There *must* be exactly one app defined for the stage for it to be valid with this type.
26 | */
27 | SINGLE,
28 |
29 | /**
30 | * If a single application is defined, it will be called directly. If more than one, the operator will be asked to choose which one to call.
31 | *
32 | * There *must* be at least one app defined for the stage for it to be valid with this type.
33 | */
34 | SINGLE_SELECT,
35 |
36 | /**
37 | * Allows for eligible applications to be selected at run time as opposed to defined statically in the configuration.
38 | *
39 | * This should be avoided for production scenarios and is intended for development and testing purposes only.
40 | */
41 | DYNAMIC_SELECT,
42 |
43 | /**
44 | * All applications defined in the list will be called in order of definition.
45 | *
46 | * There *must* be at least one app defined for the stage for it to be valid with this type.
47 | */
48 | MULTIPLE,
49 |
50 | /**
51 | * No applications will be called, regardless of what is in the apps list.
52 | */
53 | NONE
54 | }
55 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/activity_payment_approved.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
25 |
26 |
36 |
37 |
46 |
47 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/model/SystemOverview.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.model;
16 |
17 |
18 | import com.aevi.sdk.flow.model.config.FpsSettings;
19 | import com.aevi.sdk.pos.flow.model.PaymentFlowServices;
20 | import com.aevi.sdk.pos.flow.model.config.FlowConfigurations;
21 |
22 | public class SystemOverview {
23 |
24 | private int numDevices;
25 | private PaymentFlowServices paymentFlowServices;
26 | private FlowConfigurations flowConfigurations;
27 | private FpsSettings fpsSettings;
28 |
29 | public int getNumDevices() {
30 | return numDevices;
31 | }
32 |
33 | public void setNumDevices(int numDevices) {
34 | this.numDevices = numDevices;
35 | }
36 |
37 | public PaymentFlowServices getPaymentFlowServices() {
38 | return paymentFlowServices;
39 | }
40 |
41 | public void setPaymentFlowServices(PaymentFlowServices paymentFlowServices) {
42 | this.paymentFlowServices = paymentFlowServices;
43 | }
44 |
45 | public void setFlowConfigurations(FlowConfigurations flowConfigurations) {
46 | this.flowConfigurations = flowConfigurations;
47 | }
48 |
49 | public FlowConfigurations getFlowConfigurations() {
50 | return flowConfigurations;
51 | }
52 |
53 | public void setFpsSettings(FpsSettings fpsSettings) {
54 | this.fpsSettings = fpsSettings;
55 | }
56 |
57 | public FpsSettings getFpsSettings() {
58 | return fpsSettings;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/model/BaseIdNameEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.model;
16 |
17 | import androidx.annotation.NonNull;
18 |
19 | import java.util.Objects;
20 |
21 | /**
22 | * Base class for id/name pair entities.
23 | */
24 | public abstract class BaseIdNameEntity extends BaseModel {
25 |
26 | private final String name;
27 |
28 | public BaseIdNameEntity(String id, String name) {
29 | super(id);
30 | this.name = name != null ? name : "N/A";
31 | }
32 |
33 | /**
34 | * Get the name.
35 | *
36 | * @return Name
37 | */
38 | @NonNull
39 | public String getName() {
40 | return name;
41 | }
42 |
43 | @Override
44 | public boolean equals(Object o) {
45 | return doEquals(o, false);
46 | }
47 |
48 | @Override
49 | public boolean equivalent(Object o) {
50 | return doEquals(o, true);
51 | }
52 |
53 | private boolean doEquals(Object o, boolean equiv) {
54 | if (this == o) {
55 | return true;
56 | }
57 | if (o == null || getClass() != o.getClass()) {
58 | return false;
59 | }
60 | if (equiv && !super.doEquivalent(o)) {
61 | return false;
62 | } else if (!equiv && !super.equals(o)) {
63 | return false;
64 | }
65 |
66 | BaseIdNameEntity that = (BaseIdNameEntity) o;
67 | return Objects.equals(name, that.name);
68 | }
69 |
70 | @Override
71 | public int hashCode() {
72 |
73 | return Objects.hash(super.hashCode(), name);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/flow-base-api/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | apply from: gradleScript('lib/versioning.gradle')
4 | apply from: gradleScript('android/versioning.gradle')
5 | apply from: gradleScript('publish/publishing-utils.gradle')
6 | apply from: gradleScript('android/basic-library.gradle')
7 |
8 | group = 'com.aevi.sdk.flow'
9 | version = libraryVersion
10 | description = 'flow-base-api'
11 |
12 | publishingUtils?.publication {
13 | groupId group
14 | artifactId project.name
15 | version libraryVersion
16 | }
17 |
18 | apply from: gradleScript('publish/publish-maven-central.gradle')
19 |
20 | android {
21 | defaultConfig {
22 | buildConfigField("String", "NAME", "\"${project.name}\"")
23 | buildConfigField("String", "VERSION", "\"${libraryVersion}\"")
24 | buildConfigField("long", "BUILD_TIME", "${System.currentTimeMillis()}L")
25 | }
26 | }
27 |
28 | dependencies {
29 | implementation apiDependencies.gson
30 | implementation apiDependencies.rxJava
31 | implementation apiDependencies.rxMessenger
32 | implementation apiDependencies.jsonConverter
33 | implementation apiDependencies.archLifecycle
34 | implementation apiDependencies.archLifecycleJava8
35 | implementation apiDependencies.configApi
36 |
37 | testImplementation project(':payment-flow-service-api')
38 | testImplementation testDependencies.junit
39 | testImplementation testDependencies.hamcrestAll
40 | testImplementation testDependencies.mockito
41 | testImplementation testDependencies.assertJ
42 | testImplementation testDependencies.robolectric
43 | testImplementation testDependencies.androidxCore
44 | }
45 |
46 | task androidJavadocs(type: Javadoc) {
47 | source = android.sourceSets.main.java.sourceFiles
48 | source += fileTree(dir: "$buildDir/generated/source/buildConfig/release/")
49 | classpath += files(android.getBootClasspath())
50 | android.libraryVariants.all { variant ->
51 | if (variant.name == 'release') {
52 | owner.classpath += variant.javaCompileProvider.get().classpath
53 | }
54 | }
55 |
56 | title "Flow API"
57 | options.memberLevel = JavadocMemberLevel.PUBLIC
58 | failOnError false
59 | }
60 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/service/BaseResponseListenerService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.flow.service;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | import com.aevi.sdk.flow.BuildConfig;
19 | import com.aevi.sdk.flow.model.Response;
20 |
21 | /**
22 | * Extend this service in your application to listen to responses for "generic" requests and status updates initiated by your application.
23 | */
24 | public abstract class BaseResponseListenerService extends BaseListenerService {
25 |
26 | protected BaseResponseListenerService() {
27 | super(Response.class, BuildConfig.VERSION);
28 | }
29 |
30 | @Override
31 | protected final void notifyResponse(@NonNull Response response) {
32 | if (response.wasProcessedInBackground()) {
33 | notifyStatusUpdateResponse(response);
34 | } else {
35 | notifyGenericResponse(response);
36 | }
37 | }
38 |
39 | /**
40 | * Called for responses to generic flows that are processed in the foreground, such as for tokenisation or a custom request type.
41 | *
42 | * @param response The generic flow response
43 | */
44 | protected abstract void notifyGenericResponse(@NonNull Response response);
45 |
46 | /**
47 | * Called for responses to status update flows which are processed in the background.
48 | *
49 | * If you do not wish to handle such responses, you can just leave the implementation of this empty.
50 | *
51 | * @param response The status update response
52 | */
53 | protected abstract void notifyStatusUpdateResponse(@NonNull Response response);
54 | }
55 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/model/BasketItemTest.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.model;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.assertj.core.api.Java6Assertions.assertThat;
6 |
7 | public class BasketItemTest {
8 |
9 | private BasketItem defaultItem =
10 | new BasketItem("123", "Pandoras Box", "Greek Myths", 1000, 500, 2, new Measurement(2.5f, "kg"), null, null, null);
11 |
12 | @Test
13 | public void checkFieldSetCorrectly() {
14 | assertThat(defaultItem.getLabel()).isEqualTo("Pandoras Box");
15 | assertThat(defaultItem.getCategory()).isEqualTo("Greek Myths");
16 | assertThat(defaultItem.getIndividualAmount()).isEqualTo(1000);
17 | assertThat(defaultItem.getIndividualBaseAmount()).isEqualTo(500);
18 | assertThat(defaultItem.getTotalAmount()).isEqualTo(2000);
19 | assertThat(defaultItem.getTotalBaseAmount()).isEqualTo(1000);
20 | assertThat(defaultItem.getQuantity()).isEqualTo(2);
21 | assertThat(defaultItem.hasMeasurement()).isTrue();
22 | assertThat(defaultItem.getMeasurement()).isEqualTo(new Measurement(2.5f, "kg"));
23 | }
24 |
25 | @Test
26 | public void checkGetTotalFractionalAmount() throws Exception {
27 | BasketItem basketItem = new BasketItemBuilder()
28 | .withLabel("ice")
29 | .withQuantity(2)
30 | .withBaseAmountAndModifiers(500,
31 | new BasketItemModifierBuilder("tax1", "tax").withFractionalAmount(202.05f).build(),
32 | new BasketItemModifierBuilder("tax2", "tax").withPercentage(24.56f).build(),
33 | new BasketItemModifierBuilder("tax3", "tax").withAmount(200).build(),
34 | new BasketItemModifierBuilder("tax4", "tax").withFractionalAmount(-5.5f).build(),
35 | new BasketItemModifierBuilder("tax5", "tax").withPercentage(-25.003f).build()).build();
36 |
37 | float expected = 2 * (500 + 202.05f + (500 * 0.2456f) + 200 + (-5.5f) + (500 * -0.25003f));
38 | assertThat(basketItem.getTotalFractionalAmount()).isEqualTo(expected);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ConfirmationActionReceiver.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow.paymentinitiationsample;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.util.Log;
7 |
8 | import com.aevi.sdk.flow.model.FlowEvent;
9 | import com.aevi.sdk.pos.flow.PaymentApi;
10 | import com.aevi.sdk.pos.flow.PaymentClient;
11 | import com.aevi.sdk.pos.flow.model.events.ConfirmationResponse;
12 | import com.aevi.sdk.pos.flow.paymentinitiationsample.ui.NotificationHelper;
13 |
14 | import static com.aevi.sdk.flow.constants.events.FlowEventTypes.EVENT_CONFIRMATION_RESPONSE;
15 |
16 | public class ConfirmationActionReceiver extends BroadcastReceiver {
17 | private static final String TAG = ConfirmationActionReceiver.class.getSimpleName();
18 | public static final String SEND_FLOW_EVENT_RESPONSE = "com.aevi.sdk.flow.event.action.SEND";
19 |
20 | public static final String EXTRA_NOTIFICATION_ID = "notifId";
21 | public static final String EXTRA_CONFIRMATION_ID = "confId";
22 | public static final String EXTRA_RESPONSE = "response";
23 | public static final String EXTRA_ORIGINATING_ID = "originatingId";
24 |
25 | @Override
26 | public void onReceive(Context context, Intent intent) {
27 | String confId = intent.getStringExtra(EXTRA_CONFIRMATION_ID);
28 | String response = intent.getStringExtra(EXTRA_RESPONSE);
29 | String origId = intent.getStringExtra(EXTRA_ORIGINATING_ID);
30 |
31 | FlowEvent flowEvent = new FlowEvent(EVENT_CONFIRMATION_RESPONSE, new ConfirmationResponse(confId, new String[]{response}));
32 | flowEvent.setOriginatingRequestId(origId);
33 |
34 | Log.d(TAG, "Sending flow event: " + flowEvent.toJson());
35 |
36 | PaymentClient paymentClient = PaymentApi.getPaymentClient(context.getApplicationContext());
37 | paymentClient.sendEvent(flowEvent).subscribe(
38 | () -> Log.i(TAG, "FPS accepted Flow Event"),
39 | throwable -> Log.e(TAG, "Failed to send flow event", throwable));
40 |
41 | NotificationHelper notificationHelper = new NotificationHelper(context);
42 | notificationHelper.dismissNotification();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/payment-initiation-api/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | apply from: gradleScript('lib/versioning.gradle')
4 | apply from: gradleScript('android/versioning.gradle')
5 | apply from: gradleScript('publish/publishing-utils.gradle')
6 | apply from: gradleScript('android/basic-library.gradle')
7 |
8 | group = 'com.aevi.sdk.pos.flow'
9 | version = libraryVersion
10 | description = 'payment-initiation-api'
11 |
12 | publishingUtils?.publication {
13 | groupId group
14 | artifactId project.name
15 | version libraryVersion
16 | }
17 |
18 | apply from: gradleScript('publish/publish-maven-central.gradle')
19 |
20 | android {
21 | defaultConfig {
22 | buildConfigField("String", "NAME", "\"${project.name}\"")
23 | buildConfigField("String", "VERSION", "\"${libraryVersion}\"")
24 | buildConfigField("long", "BUILD_TIME", "${System.currentTimeMillis()}L")
25 | }
26 | }
27 |
28 |
29 | dependencies {
30 | api project(':flow-base-api')
31 |
32 | implementation apiDependencies.gson
33 | api apiDependencies.rxJava
34 | api apiDependencies.rxMessenger
35 | api apiDependencies.jsonConverter
36 | api apiDependencies.archLifecycle
37 | api apiDependencies.archLifecycleJava8
38 |
39 | testImplementation project(':payment-flow-service-api') // So we have access to certain builders
40 | testImplementation sampleDependencies.appFlowConstants
41 | testImplementation testDependencies.junit
42 | testImplementation testDependencies.mockito
43 | testImplementation testDependencies.assertJ
44 | testImplementation testDependencies.hamcrestAll
45 | testImplementation testDependencies.robolectric
46 | testImplementation testDependencies.androidxCore
47 |
48 | }
49 |
50 | task androidJavadocs(type: Javadoc) {
51 | source = android.sourceSets.main.java.sourceFiles
52 | source += fileTree(dir: "$buildDir/generated/source/buildConfig/release/")
53 | classpath += files(android.getBootClasspath())
54 | android.libraryVariants.all { variant ->
55 | if (variant.name == 'release') {
56 | owner.classpath += variant.javaCompileProvider.get().classpath
57 | }
58 | }
59 |
60 | title "Payment API"
61 | options.memberLevel = JavadocMemberLevel.PUBLIC
62 | failOnError false
63 | }
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout/snippet_transaction.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
28 |
29 |
30 |
35 |
36 |
41 |
42 |
49 |
50 |
51 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/fragment/SystemEventFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui.fragment;
16 |
17 | import androidx.recyclerview.widget.RecyclerView;
18 | import android.view.View;
19 | import android.widget.TextView;
20 | import butterknife.BindView;
21 | import com.aevi.sdk.flow.model.FlowEvent;
22 | import com.aevi.sdk.pos.flow.paymentinitiationsample.R;
23 | import com.aevi.sdk.pos.flow.paymentinitiationsample.model.SampleContext;
24 | import com.aevi.sdk.pos.flow.paymentinitiationsample.ui.adapter.SystemEventAdapter;
25 |
26 | import java.util.List;
27 |
28 | public class SystemEventFragment extends BaseFragment {
29 |
30 | @BindView(R.id.items)
31 | RecyclerView infoItems;
32 |
33 | @BindView(R.id.title)
34 | TextView title;
35 |
36 | @BindView(R.id.no_items)
37 | TextView noEvents;
38 |
39 | @Override
40 | public int getLayoutResource() {
41 | return R.layout.fragment_recycler_view;
42 | }
43 |
44 | @Override
45 | public void onResume() {
46 | super.onResume();
47 | setupRecyclerView(infoItems);
48 | title.setText(R.string.system_events);
49 | List receivedFlowEvents = SampleContext.getInstance(getActivity()).getSystemEventHandler().getReceivedFlowEvents();
50 | if (!receivedFlowEvents.isEmpty()) {
51 | infoItems.setAdapter(new SystemEventAdapter(receivedFlowEvents, null));
52 | } else {
53 | infoItems.setVisibility(View.GONE);
54 | noEvents.setVisibility(View.VISIBLE);
55 | noEvents.setText(R.string.no_events);
56 | }
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/PaymentServiceSample/src/main/res/layout/activity_select_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
22 |
23 |
27 |
28 |
40 |
41 |
42 |
48 |
49 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/events/FinalAmountRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.pos.flow.model.events;
15 |
16 | import java.util.Objects;
17 |
18 | /**
19 | * Final amount event request
20 | *
21 | * Usually issued by a payment service when a final amount is required for a previously provisional one
22 | *
23 | * The request can optionally contain a timeout which indicates how long the payment service will
24 | * wait for a {@link FinalAmountResponse} to be returned.
25 | */
26 | public class FinalAmountRequest {
27 |
28 | private int timeout = -1;
29 |
30 | public FinalAmountRequest() {
31 |
32 | }
33 |
34 | /**
35 | * Creates a final amount with a timeout in ms
36 | *
37 | * @param timeout The timeout in ms. Set to -1 if not required or 0 to indicate waiting forever.
38 | */
39 | public FinalAmountRequest(int timeout) {
40 | this.timeout = timeout;
41 | }
42 |
43 | /**
44 | * @return Number of milliseconds the payment service will wait for a response. Will be -1 if not set or 0 to indicate waiting forever.
45 | */
46 | public int getTimeout() {
47 | return timeout;
48 | }
49 |
50 | @Override
51 | public boolean equals(Object o) {
52 | if (this == o) return true;
53 | if (o == null || getClass() != o.getClass()) return false;
54 | FinalAmountRequest that = (FinalAmountRequest) o;
55 | return timeout == that.timeout;
56 | }
57 |
58 | @Override
59 | public int hashCode() {
60 | return Objects.hash(timeout);
61 | }
62 |
63 | @Override
64 | public String toString() {
65 | return "FinalAmountRequest{" +
66 | "timeout=" + timeout +
67 | '}';
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/main/java/com/aevi/sdk/pos/flow/model/events/ConfirmationOption.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.aevi.sdk.pos.flow.model.events;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | import java.util.Objects;
19 |
20 | /**
21 | * Represents a confirmation option consisting of some text value to display.
22 | *
23 | * To be included in a {@link ConfirmationRequest} when required
24 | */
25 | public class ConfirmationOption {
26 |
27 | @NonNull
28 | private final String value;
29 |
30 | @NonNull
31 | private final String label;
32 |
33 | public ConfirmationOption(@NonNull String value, @NonNull String label) {
34 | this.value = value;
35 | this.label = label;
36 | }
37 |
38 | /**
39 | * @return The value of the confirmation option
40 | */
41 | @NonNull
42 | public String getValue() {
43 | return value;
44 | }
45 |
46 | /**
47 | * @return A label that should be shown for the value to be selected
48 | */
49 | @NonNull
50 | public String getLabel() {
51 | return label;
52 | }
53 |
54 | @Override
55 | public boolean equals(Object o) {
56 | if (this == o) return true;
57 | if (o == null || getClass() != o.getClass()) return false;
58 | ConfirmationOption that = (ConfirmationOption) o;
59 | return value.equals(that.value) &&
60 | label.equals(that.label);
61 | }
62 |
63 | @Override
64 | public int hashCode() {
65 | return Objects.hash(value, label);
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return "ConfirmationOption{" +
71 | "value='" + value + '\'' +
72 | ", label='" + label + '\'' +
73 | '}';
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/payment-initiation-api/src/test/java/com/aevi/sdk/pos/flow/ApiTestBase.java:
--------------------------------------------------------------------------------
1 | package com.aevi.sdk.pos.flow;
2 |
3 |
4 | import android.app.Service;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.ResolveInfo;
8 | import android.content.pm.ServiceInfo;
9 | import android.os.Handler;
10 | import android.os.IBinder;
11 | import android.os.Message;
12 | import android.os.Messenger;
13 | import com.aevi.sdk.flow.BaseApiClient;
14 | import org.robolectric.RuntimeEnvironment;
15 | import org.robolectric.Shadows;
16 | import org.robolectric.shadows.ShadowApplication;
17 | import org.robolectric.shadows.ShadowPackageManager;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | import static org.mockito.Mockito.mock;
23 |
24 | import androidx.test.core.app.ApplicationProvider;
25 |
26 | public class ApiTestBase extends BaseApiClient {
27 |
28 | protected ApiTestBase(String version) {
29 | super(version, mock(Context.class));
30 | }
31 |
32 | protected void setupMockBoundMessengerService() {
33 | ShadowApplication shadowApplication = ShadowApplication.getInstance();
34 | MockMessageService mockMessageService = new MockMessageService();
35 |
36 | shadowApplication
37 | .setComponentNameAndServiceForBindService(FLOW_PROCESSING_SERVICE_COMPONENT, mockMessageService.onBind(null));
38 |
39 | Intent intent = new Intent();
40 | intent.setComponent(FLOW_PROCESSING_SERVICE_COMPONENT);
41 |
42 | ShadowPackageManager shadowPackageManager = Shadows.shadowOf(ApplicationProvider.getApplicationContext().getPackageManager());
43 | ResolveInfo resolveInfo = new ResolveInfo();
44 | resolveInfo.serviceInfo = new ServiceInfo();
45 | shadowPackageManager.addResolveInfoForIntent(intent, resolveInfo);
46 | }
47 |
48 | class MockMessageService extends Service {
49 |
50 | List messages = new ArrayList<>();
51 |
52 | class IncomingHandler extends Handler {
53 |
54 | @Override
55 | public void handleMessage(Message msg) {
56 | messages.add(msg);
57 | }
58 | }
59 |
60 | private final Messenger incomingMessenger = mock(Messenger.class);
61 |
62 | @Override
63 | public IBinder onBind(Intent intent) {
64 | return incomingMessenger.getBinder();
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/java/com/aevi/sdk/pos/flow/paymentinitiationsample/ui/fragment/BaseItemFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.pos.flow.paymentinitiationsample.ui.fragment;
16 |
17 |
18 | import android.os.Bundle;
19 | import androidx.recyclerview.widget.RecyclerView;
20 | import android.view.LayoutInflater;
21 | import android.view.MenuItem;
22 | import android.view.View;
23 | import android.view.ViewGroup;
24 | import android.widget.TextView;
25 | import butterknife.BindView;
26 | import com.aevi.sdk.pos.flow.paymentinitiationsample.R;
27 | import com.aevi.ui.library.recycler.AbstractListWithMenuAdapter;
28 |
29 | public abstract class BaseItemFragment extends BaseFragment implements AbstractListWithMenuAdapter.OnItemSelectedListener {
30 |
31 | @BindView(R.id.items)
32 | RecyclerView items;
33 |
34 | @BindView(R.id.title)
35 | TextView title;
36 |
37 | @BindView(R.id.no_items)
38 | TextView noItemsText;
39 |
40 | @Override
41 | public int getLayoutResource() {
42 | return R.layout.fragment_recycler_view;
43 | }
44 |
45 | @Override
46 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
47 | View v = super.onCreateView(inflater, container, savedInstanceState);
48 | setupRecyclerView(items);
49 | return v;
50 | }
51 |
52 | @Override
53 | public void onResume() {
54 | super.onResume();
55 | setupItems();
56 | }
57 |
58 | protected abstract void setupItems();
59 |
60 | protected void showNoItemsAvailable(int resId) {
61 | noItemsText.setVisibility(View.VISIBLE);
62 | noItemsText.setText(resId);
63 | items.setVisibility(View.GONE);
64 | }
65 |
66 | @Override
67 | public void onMenuItemAction(T t, MenuItem menuItem) {
68 |
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/PaymentInitiationSample/src/main/res/layout-sw720dp/activity_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
28 |
29 |
37 |
38 |
39 |
47 |
48 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/constants/IntentActions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.constants;
16 |
17 | /**
18 | * AppFlow intent actions.
19 | */
20 | public interface IntentActions {
21 | String BASE_INTENT_ACTION = "com.aevi.sdk.flow.action.";
22 |
23 | // Generic stages
24 | String GENERIC_REQUEST_ACTION = BASE_INTENT_ACTION + "PROCESS_GENERIC";
25 | String POST_GENERIC_REQUEST_ACTION = BASE_INTENT_ACTION + "PROCESS_POST_GENERIC";
26 | String STATUS_UPDATE_ACTION = BASE_INTENT_ACTION + "PROCESS_STATUS_UPDATE";
27 |
28 | // Payment stages
29 | String PAYMENT_CARD_READING_STAGE_ACTION = BASE_INTENT_ACTION + "READ_PAYMENT_CARD";
30 | String TRANSACTION_PROCESSING_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_TRANSACTION";
31 | String PRE_FLOW_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_PRE_FLOW";
32 | String SPLIT_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_SPLIT";
33 | String PRE_TRANSACTION_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_PRE_TRANSACTION";
34 | String POST_CARD_READING_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_POST_CARD_READING";
35 | String POST_TRANSACTION_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_POST_TRANSACTION";
36 | String POST_FLOW_STAGE_ACTION = BASE_INTENT_ACTION + "PROCESS_POST_FLOW";
37 |
38 | // Response listeners
39 | String GENERIC_RESPONSE_ACTION = BASE_INTENT_ACTION + "PROCESS_RESPONSE";
40 | String PAYMENT_RESPONSE_ACTION = BASE_INTENT_ACTION + "PROCESS_PAYMENT_RESPONSE";
41 |
42 | // Provider actions
43 | String SERVICE_INFO_PROVIDER_ACTION = BASE_INTENT_ACTION + "PROVIDE_SERVICE_INFO";
44 | String SERVICE_INFO_CHANGE_ACTION = BASE_INTENT_ACTION + "PROCESS_SERVICE_INFO_CHANGE";
45 |
46 | // Activity related
47 | String ACTIVITY_PROXY_ACTION_PREFIX = "PROCESS_";
48 | String ACTIVITY_PROXY_ACTION_POSTFIX = "_IN_ACTIVITY";
49 |
50 | }
--------------------------------------------------------------------------------
/flow-base-api/src/main/java/com/aevi/sdk/flow/model/BaseModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.aevi.sdk.flow.model;
16 |
17 |
18 | import androidx.annotation.NonNull;
19 |
20 | import com.aevi.util.json.Sendable;
21 |
22 | public abstract class BaseModel implements Sendable {
23 |
24 | private final String id;
25 |
26 | protected BaseModel(String id) {
27 | this.id = id != null ? id : "N/A";
28 | }
29 |
30 | /**
31 | * Get the id of this model.
32 | *
33 | * @return The id.
34 | */
35 | @Override
36 | @NonNull
37 | public String getId() {
38 | return id;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "{" + "id='" + id + '\'' + '}';
44 | }
45 |
46 | @Override
47 | public boolean equals(Object o) {
48 | if (this == o) {
49 | return true;
50 | }
51 | if (o == null || getClass() != o.getClass()) {
52 | return false;
53 | }
54 |
55 | BaseModel baseModel = (BaseModel) o;
56 |
57 | return id != null ? id.equals(baseModel.id) : baseModel.id == null;
58 | }
59 |
60 | /**
61 | * Used to check that an AppFlow object is equivalent to this one.
62 | *
63 | * i.e. All the same field values but a different id
64 | *
65 | * @param o The object to compare to
66 | * @return True if the obect given is equivalent
67 | */
68 | abstract public boolean equivalent(Object o);
69 |
70 | protected boolean doEquivalent(Object o) {
71 | if (this == o) {
72 | return true;
73 | }
74 | if (o == null || getClass() != o.getClass()) {
75 | return false;
76 | }
77 |
78 | return true;
79 | }
80 |
81 | @Override
82 | public int hashCode() {
83 | return id != null ? id.hashCode() : 0;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------