diff --git a/Examples/Example-Java/app/build.gradle b/Examples/Example-Java/app/build.gradle index 053532a..0ec57ae 100644 --- a/Examples/Example-Java/app/build.gradle +++ b/Examples/Example-Java/app/build.gradle @@ -43,6 +43,7 @@ dependencies { implementation "com.zettle.sdk.feature.qrc:core:$zettle_version" implementation "com.zettle.sdk.feature.qrc:paypal-ui:$zettle_version" implementation "com.zettle.sdk.feature.qrc:venmo-ui:$zettle_version" + implementation "com.zettle.sdk.feature.manualcardentry:ui:$zettle_version" implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' diff --git a/Examples/Example-Java/app/src/main/AndroidManifest.xml b/Examples/Example-Java/app/src/main/AndroidManifest.xml index 9314f06..f5da0d3 100644 --- a/Examples/Example-Java/app/src/main/AndroidManifest.xml +++ b/Examples/Example-Java/app/src/main/AndroidManifest.xml @@ -32,7 +32,9 @@ - + zettleSDK.login(this, Color.WHITE)); - logoutButton.setOnClickListener( v -> zettleSDK.logout()); + logoutButton.setOnClickListener( v -> zettleSDK.logout(null)); openCardReaderButton.setOnClickListener( v -> { Intent intent = new Intent(this, CardReaderActivity.class); @@ -51,6 +54,11 @@ public void onCreate(Bundle savedInstanceState) { Intent intent = new Intent(this, PayPalQrcActivity.class); startActivity(intent); }); + + openManualCardEntryButton.setOnClickListener( v -> { + Intent intent = new Intent(this, ManualCardEntryActivity.class); + startActivity(intent); + }); } @SuppressLint("SetTextI18n") diff --git a/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/MainApplication.java b/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/MainApplication.java index 1cc9842..6116f3e 100644 --- a/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/MainApplication.java +++ b/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/MainApplication.java @@ -11,6 +11,7 @@ import com.zettle.sdk.feature.cardreader.ui.CardReaderFeature; import com.zettle.sdk.feature.qrc.paypal.PayPalQrcFeature; import com.zettle.sdk.feature.qrc.venmo.VenmoQrcFeature; +import com.zettle.sdk.feature.manualcardentry.ui.ManualCardEntryFeature; public class MainApplication extends MultiDexApplication { @@ -47,6 +48,7 @@ public void initZettleSDK(boolean devMode) { config.addFeature(CardReaderFeature.Configuration); config.addFeature(PayPalQrcFeature.Configuration); config.addFeature(VenmoQrcFeature.Configuration); + config.addFeature(ManualCardEntryFeature.Configuration); ZettleSDK.configure(config); ProcessLifecycleOwner.get().getLifecycle().addObserver(new ZettleSDKLifecycle()); diff --git a/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/ManualCardEntryActivity.java b/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/ManualCardEntryActivity.java new file mode 100644 index 0000000..fd130ed --- /dev/null +++ b/Examples/Example-Java/app/src/main/java/com/zettle/payments/android/java_example/ManualCardEntryActivity.java @@ -0,0 +1,166 @@ +package com.zettle.payments.android.java_example; + +import androidx.appcompat.app.AppCompatActivity; + +import android.widget.Button; +import android.widget.EditText; + +import androidx.lifecycle.MutableLiveData; + +import android.os.Bundle; + +import static com.zettle.payments.android.java_example.Utils.parseLong; + +import android.app.Activity; +import android.content.Intent; +import android.text.SpannableStringBuilder; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; + +import com.google.android.material.snackbar.Snackbar; +import com.zettle.sdk.feature.manualcardentry.ui.ManualCardEntryAction; +import com.zettle.sdk.feature.manualcardentry.ui.payments.ManualCardEntryPaymentResult; +import com.zettle.sdk.features.ActionUtils; +import com.zettle.sdk.features.Transaction; +import com.zettle.sdk.ui.ZettleResult; +import com.zettle.sdk.ui.ZettleResultKt; + +import java.util.Objects; +import java.util.UUID; + +public class ManualCardEntryActivity extends AppCompatActivity { + + private Button chargeButton; + private Button settingsButton; + private EditText amountEditText; + private Button refundButton; + private Button retrieveButton; + private EditText refundAmountEditText; + private MutableLiveData lastPaymentTraceId; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_manual_card_entry); + chargeButton = findViewById(R.id.charge_btn); + settingsButton = findViewById(R.id.settings_btn); + amountEditText = findViewById(R.id.amount_input); + refundButton = findViewById(R.id.refund_btn); + retrieveButton = findViewById(R.id.retrieve_btn); + refundAmountEditText = findViewById(R.id.refund_amount_input); + lastPaymentTraceId = new MutableLiveData<>(); + + chargeButton.setOnClickListener(v -> onChargeClicked()); + settingsButton.setOnClickListener(v -> onSettingsClicked()); + refundButton.setOnClickListener(v -> onRefundLastPayment()); + retrieveButton.setOnClickListener(v -> onRetrieveLastPayment()); + } + + private final ActivityResultLauncher paymentLauncher = registerForActivityResult(new StartActivityForResult(), result -> { + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + ZettleResult parsed = ZettleResultKt.zettleResult(result.getData()); + if (parsed instanceof ZettleResult.Completed) { + showSnackBar("Payment completed"); + ManualCardEntryPaymentResult.Completed casted = (ManualCardEntryPaymentResult.Completed) parsed; + lastPaymentTraceId.setValue(Objects.requireNonNull(casted.getPayload().getReferenceId())); + refundAmountEditText.setText(new SpannableStringBuilder() + .append(String.valueOf(casted.getPayload().getAmount()))); + } else if (parsed instanceof ZettleResult.Failed) { + showSnackBar("Payment failed " + ((ZettleResult.Failed) parsed).getReason()); + } else if (parsed instanceof ZettleResult.Cancelled) { + showSnackBar("Payment canceled"); + } + } + }); + + private final ActivityResultLauncher refundLauncher = registerForActivityResult(new StartActivityForResult(), result -> { + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + ZettleResult parsed = ZettleResultKt.zettleResult(result.getData()); + if (parsed instanceof ZettleResult.Completed) { + showSnackBar("Refund completed"); + } else if (parsed instanceof ZettleResult.Failed) { + showSnackBar("Refund failed " + ((ZettleResult.Failed) parsed).getReason()); + } else if (parsed instanceof ZettleResult.Cancelled) { + showSnackBar("Refund canceled"); + } + } + }); + + private void showSnackBar(String text) { + ViewGroup viewGroup = findViewById(android.R.id.content); + Snackbar.make(viewGroup.getChildAt(0), text, Snackbar.LENGTH_LONG).show(); + } + + private void onChargeClicked() { + Long amount = parseLong(amountEditText.getText()); + if (amount == null) { + showSnackBar("Invalid amount"); + return; + } + + String uuid = UUID.randomUUID().toString(); + Intent intent; + ManualCardEntryAction.Payment payment = new ManualCardEntryAction.Payment(amount, uuid); + intent = ActionUtils.charge(payment, this); + paymentLauncher.launch(intent); + } + + private void onRefundLastPayment() { + Long amount = parseLong(refundAmountEditText.getText()); + String internalTraceId = lastPaymentTraceId.getValue(); + boolean isDevMode = ((MainApplication) getApplication()).isDevMode(); + + if (internalTraceId == null && !isDevMode) { + showSnackBar("No payment taken"); + return; + } + if (internalTraceId == null) { + internalTraceId = ""; + } + if (amount == null) { + amount = ActionUtils.FULL_REFUND; + } + + String uuid = UUID.randomUUID().toString(); + Intent intent; + ManualCardEntryAction.Refund refund = new ManualCardEntryAction.Refund(amount, internalTraceId, uuid); + intent = ActionUtils.refund(refund, this); + refundLauncher.launch(intent); + } + + private void onRetrieveLastPayment() { + String internalTraceId = lastPaymentTraceId.getValue(); + boolean isDevMode = ((MainApplication) getApplication()).isDevMode(); + + if (internalTraceId == null && !isDevMode) { + showSnackBar("No payment taken"); + return; + } + if (internalTraceId == null) { + internalTraceId = ""; + } + + Transaction transaction = new ManualCardEntryAction.Transaction(internalTraceId); + + ActionUtils.retrieve(transaction, result -> { + if (result instanceof ZettleResult.Completed) { + showSnackBar("Retrieve completed"); + } else if (result instanceof ZettleResult.Failed) { + showSnackBar("Retrieve failed " + ((ZettleResult.Failed) result).getReason()); + } else if (result instanceof ZettleResult.Cancelled) { + showSnackBar("Retrieve canceled"); + } + return null; + }); + } + + private void onSettingsClicked() { + Intent intent; + ManualCardEntryAction.Activation action = ManualCardEntryAction.Activation.INSTANCE; + intent = ActionUtils.show(action, this); + startActivity(intent); + } +} + diff --git a/Examples/Example-Java/app/src/main/res/layout/activity_main.xml b/Examples/Example-Java/app/src/main/res/layout/activity_main.xml index b74bbb6..3bc220d 100644 --- a/Examples/Example-Java/app/src/main/res/layout/activity_main.xml +++ b/Examples/Example-Java/app/src/main/res/layout/activity_main.xml @@ -103,5 +103,12 @@ android:layout_marginTop="8dp" android:text="Open PayPal QRC" /> +