Skip to content

Commit a3bda46

Browse files
committed
Merge branch 'payone' into 0.52.x
# Conflicts: # ui/src/main/res/values-de/strings.xml # ui/src/main/res/values-en/strings.xml # ui/src/main/res/values-hu/strings.xml # ui/src/main/res/values-sk/strings.xml # ui/src/main/res/values/strings.xml
2 parents 191ee5d + 2e5eccd commit a3bda46

File tree

18 files changed

+1078
-39
lines changed

18 files changed

+1078
-39
lines changed

core/src/main/java/io/snabble/sdk/payment/PaymentCredentials.java

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@
1616
import java.security.spec.AlgorithmParameterSpec;
1717
import java.security.spec.MGF1ParameterSpec;
1818
import java.text.SimpleDateFormat;
19-
import java.util.*;
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.Calendar;
22+
import java.util.Collections;
23+
import java.util.Date;
24+
import java.util.HashMap;
25+
import java.util.HashSet;
26+
import java.util.List;
27+
import java.util.Locale;
28+
import java.util.Map;
29+
import java.util.UUID;
2030

2131
import javax.crypto.Cipher;
2232
import javax.crypto.spec.OAEPParameterSpec;
@@ -39,7 +49,8 @@ public enum Type {
3949
PAYDIREKT(null, false, Collections.singletonList(PaymentMethod.PAYDIREKT)),
4050
TEGUT_EMPLOYEE_CARD("tegutEmployeeID", false, Collections.singletonList(PaymentMethod.TEGUT_EMPLOYEE_CARD)),
4151
DATATRANS("datatransAlias", true, Arrays.asList(PaymentMethod.TWINT, PaymentMethod.POST_FINANCE_CARD)),
42-
DATATRANS_CREDITCARD("datatransCreditCardAlias", true, Arrays.asList(PaymentMethod.VISA, PaymentMethod.MASTERCARD, PaymentMethod.AMEX));
52+
DATATRANS_CREDITCARD("datatransCreditCardAlias", true, Arrays.asList(PaymentMethod.VISA, PaymentMethod.MASTERCARD, PaymentMethod.AMEX)),
53+
PAYONE_CREDITCARD(null, true, Arrays.asList(PaymentMethod.VISA, PaymentMethod.MASTERCARD, PaymentMethod.AMEX));
4354

4455
private String originType;
4556
private boolean requiresProject;
@@ -115,6 +126,18 @@ private static class DatatransData {
115126
private String expiryYear;
116127
}
117128

129+
private static class PayoneData {
130+
PayoneData(String pseudoCardPAN, String name, String userID) {
131+
this.pseudoCardPAN = pseudoCardPAN;
132+
this.name = name;
133+
this.userID = userID;
134+
}
135+
136+
private final String pseudoCardPAN;
137+
private final String name;
138+
private final String userID;
139+
}
140+
118141
public static class PaydirektAuthorizationData {
119142
public String id;
120143
public String name;
@@ -247,18 +270,26 @@ public static PaymentCredentials fromCreditCardData(String name,
247270
return pc;
248271
}
249272

273+
@Deprecated
250274
private static long parseValidTo(String format, String expirationMonth, String expirationYear) {
251275
if (expirationMonth == null || expirationMonth.equals("")
252276
|| expirationYear == null || expirationYear.equals("")) {
253277
return 0;
254278
}
255279

280+
return parseValidTo(format, expirationMonth + "/" + expirationYear);
281+
}
282+
283+
private static long parseValidTo(String format, String expirationDate) {
284+
if (expirationDate == null || expirationDate.trim().equals("")) {
285+
return 0;
286+
}
287+
256288
try {
257-
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
258-
Date date = simpleDateFormat.parse(expirationMonth + "/" + expirationYear);
289+
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format, Locale.getDefault());
259290

260291
Calendar calendar = Calendar.getInstance();
261-
calendar.setTime(date);
292+
calendar.setTime(simpleDateFormat.parse(expirationDate));
262293
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
263294

264295
return calendar.getTimeInMillis();
@@ -355,6 +386,50 @@ public static PaymentCredentials fromDatatrans(String token, Brand brand, String
355386
return pc;
356387
}
357388

389+
public static PaymentCredentials fromPayone(String pseudocardpan,
390+
String truncatedcardpan,
391+
PaymentCredentials.Brand brand,
392+
String cardexpiredate,
393+
String lastname,
394+
String userId,
395+
String projectId) {
396+
if (pseudocardpan == null) {
397+
return null;
398+
}
399+
400+
PaymentCredentials pc = new PaymentCredentials();
401+
pc.generateId();
402+
if (brand == Brand.MASTERCARD || brand == Brand.AMEX || brand == Brand.VISA) {
403+
pc.type = Type.PAYONE_CREDITCARD;
404+
} else {
405+
return null;
406+
}
407+
pc.projectId = projectId;
408+
409+
List<X509Certificate> certificates = Snabble.getInstance().getPaymentSigningCertificates();
410+
if (certificates.size() == 0) {
411+
return null;
412+
}
413+
414+
PayoneData payoneData = new PayoneData(pseudocardpan, lastname, userId);
415+
416+
String json = GsonHolder.get().toJson(payoneData, PayoneData.class);
417+
418+
X509Certificate certificate = certificates.get(0);
419+
pc.rsaEncryptedData = pc.rsaEncrypt(certificate, json.getBytes());
420+
pc.signature = pc.sha256Signature(certificate);
421+
pc.appId = Snabble.getInstance().getConfig().appId;
422+
pc.brand = brand;
423+
pc.obfuscatedId = truncatedcardpan;
424+
pc.validTo = parseValidTo("yyMM", cardexpiredate);
425+
426+
if (pc.rsaEncryptedData == null) {
427+
return null;
428+
}
429+
430+
return pc;
431+
}
432+
358433
public static PaymentCredentials fromTegutEmployeeCard(String obfuscatedId, String cardNumber, String projectId) {
359434
if (cardNumber == null || cardNumber.length() != 19
360435
|| (!cardNumber.startsWith("9280001621")
@@ -646,6 +721,12 @@ public PaymentMethod getPaymentMethod() {
646721
case POST_FINANCE_CARD: return PaymentMethod.POST_FINANCE_CARD;
647722
case TWINT: return PaymentMethod.TWINT;
648723
}
724+
} else if (type == Type.PAYONE_CREDITCARD) {
725+
switch (getBrand()) {
726+
case VISA: return PaymentMethod.VISA;
727+
case AMEX: return PaymentMethod.AMEX;
728+
case MASTERCARD: return PaymentMethod.MASTERCARD;
729+
}
649730
}
650731

651732
return null;

java-sample/src/main/java/io/snabble/testapp/BaseActivity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ public void execute(SnabbleUI.Action action, Bundle args) {
140140
case SHOW_CREDIT_CARD_INPUT:
141141
showCreditCardInput(args);
142142
break;
143+
case SHOW_PAYONE_INPUT:
144+
showPayoneInput(args);
145+
break;
143146
case SHOW_PAYDIREKT_INPUT:
144147
showPaydirektInput();
145148
break;
@@ -235,6 +238,12 @@ public void showCreditCardInput(Bundle args) {
235238
startActivity(intent);
236239
}
237240

241+
public void showPayoneInput(Bundle args) {
242+
Intent intent = new Intent(this, PayoneInputActivity.class);
243+
intent.putExtra("args", args);
244+
startActivity(intent);
245+
}
246+
238247
public void showPaydirektInput() {
239248
Intent intent = new Intent(this, PaydirektInputActivity.class);
240249
startActivity(intent);

java-sample/src/main/java/io/snabble/testapp/CreditCardInputActivity.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ public Fragment onCreateFragment() {
1111
fragment.setArguments(getIntent().getBundleExtra("args"));
1212
return fragment;
1313
}
14-
}
15-
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.snabble.testapp;
2+
3+
import androidx.fragment.app.Fragment;
4+
5+
import io.snabble.sdk.ui.integration.PayoneInputFragment;
6+
7+
public class PayoneInputActivity extends BaseActivity {
8+
@Override
9+
public Fragment onCreateFragment() {
10+
PayoneInputFragment fragment = new PayoneInputFragment();
11+
fragment.setArguments(getIntent().getBundleExtra("args"));
12+
return fragment;
13+
}
14+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.snabble.sdk.ui.integration
2+
3+
import android.os.Bundle
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import androidx.fragment.app.Fragment
8+
import io.snabble.sdk.PaymentMethod
9+
import io.snabble.sdk.ui.payment.Payone
10+
import io.snabble.sdk.ui.payment.PayoneInputView
11+
12+
open class PayoneInputFragment : Fragment() {
13+
companion object {
14+
const val ARG_PROJECT_ID = PayoneInputView.ARG_PROJECT_ID
15+
const val ARG_PAYMENT_TYPE = PayoneInputView.ARG_PAYMENT_TYPE
16+
const val ARG_TOKEN_DATA = PayoneInputView.ARG_TOKEN_DATA
17+
}
18+
19+
private lateinit var projectId: String
20+
private lateinit var paymentMethod: PaymentMethod
21+
private lateinit var tokenizationData: Payone.PayoneTokenizationData
22+
23+
override fun onCreate(savedInstanceState: Bundle?) {
24+
super.onCreate(savedInstanceState)
25+
setHasOptionsMenu(true)
26+
27+
projectId = requireNotNull(arguments?.getString(ARG_PROJECT_ID, null))
28+
paymentMethod = requireNotNull(arguments?.getSerializable(ARG_PAYMENT_TYPE) as? PaymentMethod)
29+
tokenizationData = requireNotNull(arguments?.getParcelable(ARG_TOKEN_DATA))
30+
}
31+
32+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
33+
inflater.inflate(R.layout.snabble_fragment_cardinput_payone, container, false).apply {
34+
findViewById<PayoneInputView>(R.id.user_payment_method_view).load(projectId, paymentMethod, tokenizationData)
35+
}
36+
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<io.snabble.sdk.ui.payment.CreditCardInputView xmlns:android="http://schemas.android.com/apk/res/android"
2+
<io.snabble.sdk.ui.payment.CreditCardInputView
3+
xmlns:android="http://schemas.android.com/apk/res/android"
34
android:id="@+id/user_payment_method_view"
45
android:layout_width="match_parent"
5-
android:layout_height="match_parent">
6-
7-
</io.snabble.sdk.ui.payment.CreditCardInputView>
6+
android:layout_height="match_parent"/>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<io.snabble.sdk.ui.payment.PayoneInputView
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:id="@+id/user_payment_method_view"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"/>

ui/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ apply plugin: 'com.android.library'
22
apply plugin: 'kotlin-android'
33
apply from: '../scripts/maven.gradle'
44
apply plugin: 'org.jetbrains.dokka'
5+
apply plugin: "org.jetbrains.kotlin.plugin.parcelize"
56

67
android {
78
compileSdkVersion project.compileSdkVersion
@@ -53,7 +54,7 @@ dependencies {
5354
implementation project(':utils')
5455
implementation project(':core')
5556

56-
implementation 'androidx.core:core-ktx:1.6.0'
57+
implementation 'androidx.core:core-ktx:1.7.0'
5758
implementation 'androidx.appcompat:appcompat:1.3.1'
5859
implementation 'androidx.recyclerview:recyclerview:1.2.1'
5960
implementation 'androidx.cardview:cardview:1.0.0'
@@ -65,10 +66,10 @@ dependencies {
6566
implementation 'me.relex:circleindicator:2.1.6'
6667
implementation 'ch.datatrans:android-sdk:1.4.2'
6768
implementation 'com.google.android.gms:play-services-wallet:18.1.3'
68-
implementation 'eu.rekisoft.android.util:LazyWorker:2.0.2'
69+
implementation 'eu.rekisoft.android.util:LazyWorker:2.1.0'
6970
implementation 'androidx.biometric:biometric:1.2.0-alpha03'
7071

71-
def camerax_version = "1.0.1"
72+
def camerax_version = "1.0.2"
7273
implementation "androidx.camera:camera-core:${camerax_version}"
7374
implementation "androidx.camera:camera-camera2:${camerax_version}"
7475
implementation "androidx.camera:camera-lifecycle:${camerax_version}"

ui/src/main/java/io/snabble/sdk/ui/SnabbleUI.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public enum Action {
2727
SHOW_BARCODE_SEARCH,
2828
SHOW_SEPA_CARD_INPUT,
2929
SHOW_CREDIT_CARD_INPUT,
30+
SHOW_PAYONE_INPUT,
3031
SHOW_PAYDIREKT_INPUT,
3132
SHOW_SHOPPING_CART,
3233
SHOW_PAYMENT_CREDENTIALS_LIST,

ui/src/main/java/io/snabble/sdk/ui/cart/CheckoutBar.kt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,10 @@ open class CheckoutBar @JvmOverloads constructor(
225225
})
226226
}
227227
} else {
228-
var hasPaymentMethodThatRequiresCredentials = false
229-
val paymentMethodsDescriptors = project.paymentMethodDescriptors
230-
if (paymentMethodsDescriptors != null && paymentMethodsDescriptors.isNotEmpty()) {
231-
for (descriptor in paymentMethodsDescriptors) {
232-
if (descriptor.paymentMethod.isRequiringCredentials) {
233-
hasPaymentMethodThatRequiresCredentials = true
234-
break
235-
}
236-
}
237-
}
228+
val hasPaymentMethodThatRequiresCredentials =
229+
project.paymentMethodDescriptors?.any { descriptor ->
230+
descriptor.paymentMethod.isRequiringCredentials
231+
} ?: false
238232
if (hasPaymentMethodThatRequiresCredentials) {
239233
val activity = UIUtils.getHostActivity(context)
240234
if (activity is FragmentActivity) {

0 commit comments

Comments
 (0)