Skip to content

Commit a4357b1

Browse files
authored
Merge pull request #16 from snabble/routing_targets
Activity API + RoutingTargets
2 parents 13e56c1 + 64f8dcd commit a4357b1

File tree

181 files changed

+2026
-2260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+2026
-2260
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## [0.60.0-alpha02]
5+
6+
### Changes
7+
- Add support for new Routing Targets API
8+
9+
## [0.60.0-alpha01]
10+
11+
### Breaking Changes
12+
- Removed 'ui-integration' module and integrated it into 'ui'
13+
- All Fragments have its package name changed due to this.
14+
- Now supporting Activities for all screens. For example 'SelfScanningActivity' for the Scanner.
15+
Refer to the Documentation for a list of all Activites/Fragments and View's
16+
- Removed SnabbleUI.registerUiCallbacks in favor of SnabbleUI.setUiAction
17+
- UI Callback are now entirely optional, and Activites will be launched if a UI Event is not implemented
18+
by the hosting application
19+
- Upgrading from 0.52.x requires the callbacks to be changed, but the general flow is the same if you were using Fragments
20+
- Cleanup is done automatically, no SnabbleUI.unregisterUiCallbacks is necessary anymore!
21+
- Checkout is now done in it's own Activity and can be started by using CheckoutActivity.startCheckoutFlow
22+
23+
### Notes
24+
- Toolbar can be enabled in Activities by setting **snabbleToolbarStyle** in your Application theme
25+
426
## [0.53.0]
527

628
### Changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ dependencies {
3737
3838
// user interface library
3939
implementation 'io.snabble.sdk:ui:{currentVersion}'
40-
41-
// user interface integration library, entirely optional,
42-
// for more seamless and easier integration in apps
43-
implementation 'io.snabble.sdk:ui-integration:{currentVersion}'
4440
}
4541
```
4642

build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@ allprojects {
3131
}
3232

3333
project.ext {
34-
sdkVersion='0.53.0'
34+
sdkVersion='0.60.0-alpha02'
3535
versionCode=1
3636

3737
compileSdkVersion=31
3838
minSdkVersion=21
3939
targetSdkVersion=31
4040

41-
buildToolsVersion='30.0.2'
4241
okhttpVersion='4.9.1'
4342
desugarVersion='1.1.5'
4443

core/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ apply plugin: 'org.jetbrains.dokka'
66

77
android {
88
compileSdkVersion project.compileSdkVersion
9-
buildToolsVersion project.buildToolsVersion
109

1110
defaultConfig {
1211
minSdkVersion project.minSdkVersion

core/src/main/java/io/snabble/sdk/Checkout.java

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ public enum State {
5555
*/
5656
REQUEST_PAYMENT_AUTHORIZATION_TOKEN,
5757
/**
58-
* Payment was received by the backend and we are waiting for confirmation of the payment provider
58+
* Checkout was received and we wait for confirmation by the supervisor
59+
*/
60+
WAIT_FOR_SUPERVISOR,
61+
/**
62+
* Checkout was received and we wait for confirmation by the gatekeeper
63+
*/
64+
WAIT_FOR_GATEKEEPER,
65+
/**
66+
* Payment was received by the backend and we are waiting for confirmation by the payment provider
5967
*/
6068
WAIT_FOR_APPROVAL,
6169
/**
@@ -158,15 +166,15 @@ public void abort() {
158166
* was cancelled
159167
*/
160168
public void abort(boolean error) {
161-
cancelOutstandingCalls();
162-
163169
if (state != Checkout.State.PAYMENT_APPROVED
164170
&& state != Checkout.State.DENIED_BY_PAYMENT_PROVIDER
165171
&& state != Checkout.State.DENIED_BY_SUPERVISOR
166172
&& checkoutProcess != null) {
167173
checkoutApi.abort(checkoutProcess, new CheckoutApi.PaymentAbortResult() {
168174
@Override
169175
public void success() {
176+
cancelOutstandingCalls();
177+
170178
synchronized (Checkout.this) {
171179
if (error) {
172180
notifyStateChanged(Checkout.State.PAYMENT_PROCESSING_ERROR);
@@ -236,13 +244,6 @@ public void reset() {
236244
shop = null;
237245
}
238246

239-
public void resume() {
240-
if (lastState == Checkout.State.WAIT_FOR_APPROVAL || lastState == State.REQUEST_PAYMENT_AUTHORIZATION_TOKEN) {
241-
notifyStateChanged(Checkout.State.WAIT_FOR_APPROVAL);
242-
pollForResult();
243-
}
244-
}
245-
246247
public boolean isAvailable() {
247248
return project.getCheckoutUrl() != null && project.isCheckoutAvailable();
248249
}
@@ -397,22 +398,6 @@ public void success(CheckoutApi.CheckoutProcessResponse checkoutProcessResponse,
397398
rawCheckoutProcess = rawResponse;
398399

399400
if (!handleProcessResponse()) {
400-
boolean allChecksOk = areAllChecksSucceeded(checkoutProcessResponse);
401-
402-
if (allChecksOk) {
403-
if (checkoutProcessResponse.paymentState == CheckoutApi.State.PROCESSING) {
404-
Logger.d("Processing payment...");
405-
notifyStateChanged(Checkout.State.PAYMENT_PROCESSING);
406-
} else {
407-
Logger.d("Waiting for approval...");
408-
if (paymentMethod != PaymentMethod.GOOGLE_PAY) {
409-
notifyStateChanged(Checkout.State.WAIT_FOR_APPROVAL);
410-
}
411-
}
412-
} else {
413-
notifyStateChanged(Checkout.State.WAIT_FOR_APPROVAL);
414-
}
415-
416401
if (!paymentMethod.isOfflineMethod()) {
417402
scheduleNextPoll();
418403
}
@@ -457,7 +442,7 @@ private boolean areAllChecksSucceeded(CheckoutApi.CheckoutProcessResponse checko
457442

458443
if (checkoutProcessResponse.checks != null) {
459444
for (CheckoutApi.Check check : checkoutProcessResponse.checks) {
460-
if (check.state == CheckoutApi.State.FAILED) {
445+
if (check.state != CheckoutApi.State.SUCCESSFUL) {
461446
return false;
462447
}
463448

@@ -493,6 +478,30 @@ private boolean areAllChecksSucceeded(CheckoutApi.CheckoutProcessResponse checko
493478
return allChecksOk;
494479
}
495480

481+
private boolean hasAnyCheckFailed(CheckoutApi.CheckoutProcessResponse checkoutProcessResponse) {
482+
if (checkoutProcessResponse.checks != null) {
483+
for (CheckoutApi.Check check : checkoutProcessResponse.checks) {
484+
if (check.state == CheckoutApi.State.FAILED) {
485+
return true;
486+
}
487+
}
488+
}
489+
490+
return false;
491+
}
492+
493+
private boolean hasAnyFulfillmentAllocationFailed() {
494+
if (checkoutProcess.fulfillments != null) {
495+
for (CheckoutApi.Fulfillment fulfillment : checkoutProcess.fulfillments) {
496+
if (fulfillment.state == FulfillmentState.ALLOCATION_FAILED || fulfillment.state == FulfillmentState.ALLOCATION_TIMED_OUT) {
497+
return true;
498+
}
499+
}
500+
}
501+
502+
return false;
503+
}
504+
496505
private boolean hasStillPendingChecks(CheckoutApi.CheckoutProcessResponse checkoutProcessResponse) {
497506
if (checkoutProcessResponse.checks != null) {
498507
for (CheckoutApi.Check check : checkoutProcessResponse.checks) {
@@ -569,6 +578,8 @@ private void pollForResult() {
569578

570579
Logger.d("Polling for approval state...");
571580

581+
Logger.d("RoutingTarget = " + getRoutingTarget());
582+
572583
checkoutApi.updatePaymentProcess(checkoutProcess, new CheckoutApi.PaymentProcessResult() {
573584
@Override
574585
public void success(CheckoutApi.CheckoutProcessResponse checkoutProcessResponse, String rawResponse) {
@@ -589,6 +600,8 @@ public void error() {
589600
});
590601

591602
if (state == Checkout.State.WAIT_FOR_APPROVAL
603+
|| state == State.WAIT_FOR_GATEKEEPER
604+
|| state == State.WAIT_FOR_SUPERVISOR
592605
|| state == State.VERIFYING_PAYMENT_METHOD
593606
|| state == State.REQUEST_PAYMENT_AUTHORIZATION_TOKEN
594607
|| state == Checkout.State.PAYMENT_PROCESSING
@@ -608,6 +621,18 @@ private boolean handleProcessResponse() {
608621
return true;
609622
}
610623

624+
if (state == State.VERIFYING_PAYMENT_METHOD) {
625+
if (checkoutProcess.routingTarget == CheckoutApi.RoutingTarget.SUPERVISOR) {
626+
notifyStateChanged(State.WAIT_FOR_SUPERVISOR);
627+
} else if (checkoutProcess.routingTarget == CheckoutApi.RoutingTarget.GATEKEEPER) {
628+
notifyStateChanged(State.WAIT_FOR_GATEKEEPER);
629+
} else {
630+
notifyStateChanged(State.WAIT_FOR_APPROVAL);
631+
}
632+
633+
return false;
634+
}
635+
611636
String authorizePaymentUrl = checkoutProcess.getAuthorizePaymentLink();
612637
if (authorizePaymentUrl != null) {
613638
if (authorizePaymentRequestFailed) {
@@ -651,11 +676,12 @@ private boolean handleProcessResponse() {
651676
return false;
652677
}
653678

654-
if (hasStillPendingChecks(checkoutProcess)) {
655-
notifyStateChanged(State.WAIT_FOR_APPROVAL);
679+
if (hasAnyFulfillmentAllocationFailed()) {
680+
notifyStateChanged(State.PAYMENT_ABORTED);
681+
return true;
656682
}
657683

658-
if (!areAllChecksSucceeded(checkoutProcess)) {
684+
if (hasAnyCheckFailed(checkoutProcess)) {
659685
Logger.d("Payment denied by supervisor");
660686
shoppingCart.generateNewUUID();
661687
notifyStateChanged(Checkout.State.DENIED_BY_SUPERVISOR);
@@ -708,6 +734,7 @@ public List<Coupon> getRedeemedCoupons() {
708734
public void approveOfflineMethod() {
709735
if (paymentMethod != null && paymentMethod.isOfflineMethod()
710736
|| paymentMethod == PaymentMethod.CUSTOMERCARD_POS) {
737+
shoppingCart.generateNewUUID();
711738
approve();
712739
}
713740
}
@@ -787,6 +814,14 @@ public int getVerifiedOnlinePrice() {
787814
return -1;
788815
}
789816

817+
public CheckoutApi.RoutingTarget getRoutingTarget() {
818+
if (checkoutProcess != null && checkoutProcess.routingTarget != null) {
819+
return checkoutProcess.routingTarget;
820+
}
821+
822+
return CheckoutApi.RoutingTarget.NONE;
823+
}
824+
790825
public List<Product> getInvalidProducts() {
791826
return invalidProducts;
792827
}

core/src/main/java/io/snabble/sdk/CheckoutApi.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ public static class PaymentInformation {
193193
public String deviceName;
194194
public String deviceFingerprint;
195195
public String deviceIPAddress;
196+
public String handoverInformation;
196197
}
197198

198199
public static class CheckoutProcessRequest {
@@ -285,6 +286,15 @@ public String getSelfLink() {
285286
}
286287
}
287288

289+
public enum RoutingTarget {
290+
@SerializedName("gatekeeper")
291+
GATEKEEPER,
292+
@SerializedName("supervisor")
293+
SUPERVISOR,
294+
@SerializedName("none")
295+
NONE,
296+
}
297+
288298
public static class CheckoutProcessResponse {
289299
public Map<String, Href> links;
290300
public Check[] checks;
@@ -298,6 +308,7 @@ public static class CheckoutProcessResponse {
298308
public ExitToken exitToken;
299309
public State paymentState;
300310
public Pricing pricing;
311+
public RoutingTarget routingTarget;
301312
public PaymentResult paymentResult;
302313
public Fulfillment[] fulfillments;
303314

core/src/main/java/io/snabble/sdk/Snabble.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ public List<Project> getProjects() {
448448
}
449449

450450
public Project getProjectById(String projectId) {
451+
if (projects == null) {
452+
return null;
453+
}
454+
451455
for (Project project : projects) {
452456
if (project.getId().equals(projectId)) {
453457
return project;
@@ -563,20 +567,6 @@ public interface OnMetadataUpdateListener {
563567
void onMetaDataUpdated();
564568
}
565569

566-
/**
567-
* Sets the current activity context.
568-
*
569-
* This is an internal method and should not be called.
570-
*/
571-
public void _setCurrentActivity(Activity activity) {
572-
if (currentActivity != null) {
573-
currentActivity.clear();
574-
currentActivity = null;
575-
}
576-
577-
currentActivity = new WeakReference<>(activity);
578-
}
579-
580570
private final Application.ActivityLifecycleCallbacks activityLifecycleCallbacks = new SimpleActivityLifecycleCallbacks() {
581571

582572
@Override
@@ -690,7 +680,7 @@ public Error getError() {
690680
return error;
691681
}
692682

693-
@NonNull
683+
@NonNull
694684
@Override
695685
public String toString() {
696686
return "SnabbleException{" +

docs/docs/android-api.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
minSdkVersion = 21
66
compileSdkVersion = 29
77
java 8
8-
9-
androidx and a material 3 theme for ui components
8+
androidx
109

1110
### Using the snabble GitHub Repository
1211

@@ -29,10 +28,6 @@ dependencies {
2928
3029
// user interface library
3130
implementation 'io.snabble.sdk:ui:{{ extra.sdk_version }}'
32-
33-
// user interface integration library, entirely optional,
34-
// for more seamless and easier integration in apps
35-
implementation 'io.snabble.sdk:ui-integration:{{ extra.sdk_version }}'
3631
}
3732
```
3833

@@ -83,7 +78,7 @@ snabble.setup(this, config, new Snabble.SetupCompletionListener() {
8378
project = snabble.getProjects().get(0);
8479

8580
// registers this project globally for use with ui components
86-
SnabbleUI.useProject(project);
81+
SnabbleUI.setProject(project);
8782

8883
// select the first shop for demo purposes, ideally this should be done with
8984
// geofencing or a manual user selection

0 commit comments

Comments
 (0)