· 6 years ago · Sep 30, 2019, 10:32 PM
1package unknown_studios.com.izumiandroid.Activities;
2
3import android.app.Activity;
4import android.content.DialogInterface;
5import android.content.Intent;
6import android.graphics.Color;
7import android.os.AsyncTask;
8import android.os.Bundle;
9import android.util.Log;
10import android.view.MenuItem;
11import android.view.View;
12import android.widget.Button;
13import android.widget.ProgressBar;
14import android.widget.TextView;
15import android.widget.Toast;
16
17import androidx.annotation.NonNull;
18import androidx.annotation.Nullable;
19import androidx.appcompat.app.AppCompatActivity;
20import androidx.appcompat.widget.Toolbar;
21
22import com.android.volley.DefaultRetryPolicy;
23import com.android.volley.Request;
24import com.android.volley.RequestQueue;
25import com.android.volley.Response;
26import com.android.volley.VolleyError;
27import com.android.volley.toolbox.StringRequest;
28import com.android.volley.toolbox.Volley;
29import com.google.android.gms.common.api.ApiException;
30import com.google.android.gms.common.api.Status;
31import com.google.android.gms.wallet.AutoResolveHelper;
32import com.google.android.gms.wallet.CardRequirements;
33import com.google.android.gms.wallet.IsReadyToPayRequest;
34import com.google.android.gms.wallet.PaymentData;
35import com.google.android.gms.wallet.PaymentDataRequest;
36import com.google.android.gms.wallet.PaymentMethodTokenizationParameters;
37import com.google.android.gms.wallet.PaymentsClient;
38import com.google.android.gms.wallet.TransactionInfo;
39import com.google.android.gms.wallet.Wallet;
40import com.google.android.gms.wallet.WalletConstants;
41import com.google.android.material.bottomnavigation.BottomNavigationView;
42import com.google.firebase.Timestamp;
43import com.google.firebase.auth.FirebaseAuth;
44import com.google.firebase.firestore.DocumentSnapshot;
45import com.google.firebase.firestore.FirebaseFirestore;
46import com.google.gson.Gson;
47import com.google.gson.GsonBuilder;
48import com.google.gson.JsonArray;
49import com.stripe.android.ApiResultCallback;
50import com.stripe.android.PaymentConfiguration;
51import com.stripe.android.PaymentIntentResult;
52import com.stripe.android.Stripe;
53import com.stripe.android.exception.APIConnectionException;
54import com.stripe.android.exception.APIException;
55import com.stripe.android.exception.AuthenticationException;
56import com.stripe.android.exception.InvalidRequestException;
57import com.stripe.android.model.PaymentIntent;
58import com.stripe.android.model.PaymentMethod;
59import com.stripe.android.model.PaymentMethodCreateParams;
60import com.stripe.android.view.PaymentMethodsActivityStarter;
61import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
62import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
63
64import org.json.JSONException;
65import org.json.JSONObject;
66
67import java.util.ArrayList;
68import java.util.Arrays;
69import java.util.Calendar;
70import java.util.Date;
71import java.util.HashMap;
72import java.util.List;
73import java.util.Random;
74
75import unknown_studios.com.izumiandroid.BuildConfig;
76import unknown_studios.com.izumiandroid.Classes.User;
77import unknown_studios.com.izumiandroid.Helpers.NetworkManager.NetworkManager;
78import unknown_studios.com.izumiandroid.Helpers.NetworkManager.UserCallback;
79import unknown_studios.com.izumiandroid.R;
80import unknown_studios.com.izumiandroid.Classes.Order;
81
82import static android.view.View.GONE;
83import static java.lang.Math.toIntExact;
84
85public class CheckoutActivity extends AppCompatActivity implements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
86
87 public static String Tag = "CheckoutActivity";
88 public static Timestamp ts = null;
89 private static final int LOAD_PAYMENT_DATA_REQUEST_CODE = 53;
90 Calendar calendar = null;
91 PaymentMethod payMethod;
92 Stripe mStripe;
93 PaymentsClient paymentsClient;
94 private DatePickerDialog dpd;
95 private TimePickerDialog tpd;
96
97 void launchWithCustomer() {
98 CardActivity.returnActivity = CardActivity.ReturnActivity.CheckoutActivity ;
99 Intent intent = new Intent(CheckoutActivity.this, CardActivity.class);
100 startActivity(intent);
101 }
102
103 @Override
104 protected void onNewIntent(Intent intent) {
105 super.onNewIntent(intent);
106 if (intent.getData() != null && intent.getData().getQuery() != null) {
107 final String host = intent.getData().getHost();
108 final String clientSecret = intent.getData().getQueryParameter("payment_intent_client_secret");
109
110 FirebaseAuth fa = FirebaseAuth.getInstance();
111 final String email = fa.getCurrentUser().getEmail();
112
113 Load(false);
114
115 AsyncTask.execute(() -> {
116 // retrieve the PaymentIntent on a background thread
117 try {
118 final PaymentIntent paymentIntent = mStripe.retrievePaymentIntentSynchronous(clientSecret);
119 if (paymentIntent.requiresAction()) {
120 performAction(paymentIntent, PaymentActivity.takeawayID);
121 } else {
122 FirebaseFirestore db = FirebaseFirestore.getInstance();
123 db.collection("restaurants").whereEqualTo("identifier", MainActivity.restaurantIdentifier).get().addOnCompleteListener(task -> {
124 String stripeKey = (String)task.getResult().getDocuments().get(0).get("StripeKey");
125
126 RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
127 String url;
128 if (PaymentActivity.takeawayID.equals("")) {
129 url = "https://europe-west1-izumi-475a0.cloudfunctions.net/pay?email=" + email + "&payment_intent_id=" + paymentIntent.getId() + "&tableNumber=" + MainActivity.TableNumber + "&identifier=" + MainActivity.restaurantIdentifier;
130 } else {
131 url = "https://europe-west1-izumi-475a0.cloudfunctions.net/pay?email=" + email + "&payment_intent_id=" + paymentIntent.getId() + "&takeaway=" + PaymentActivity.takeawayID;
132 }
133
134 StringRequest stringRequest = new StringRequest(Request.Method.GET, url, response -> {
135 final String Response = response;
136
137 AsyncTask.execute(() -> {
138 try {
139 JSONObject piObj = new JSONObject(Response);
140 if (piObj.has("error")) {
141 if (piObj.getString("error").startsWith("No users needed payment")) { //No users needed payment
142 FirebaseFirestore fs = FirebaseFirestore.getInstance();
143 fs.collection("orders")
144 .whereEqualTo("tableNumber", MainActivity.TableNumber)
145 .whereEqualTo("identifier", MainActivity.restaurantIdentifier)
146 .get().addOnCompleteListener(task1 -> {
147 if (!task1.isSuccessful()) {
148 Log.e(Tag, "Got the following error: ", task1.getException());
149 return;
150 }
151 List<DocumentSnapshot> docs = task1.getResult().getDocuments();
152 if (docs.size() == 0) {
153 Log.d(Tag, "Got zero documents with the information provided");
154 return;
155 }
156 boolean gotSomething = false;
157 CompleteOrderActivity.currentTableOrder.clear();
158 for (int i = 0; i < docs.size(); i++) {
159 Boolean paid = (Boolean) docs.get(i).get("Paid");
160 Long tn = (Long)docs.get(i).get("tableNumber");
161 int table = toIntExact(tn);
162 if ((paid == null || !paid) && table != 0) {
163 gotSomething = true;
164 }
165 }
166
167 if (gotSomething) {
168 Toast.makeText(getApplicationContext(), "An error happened and there are still items left to pay for", Toast.LENGTH_LONG).show();
169 Intent intent1 = new Intent(CheckoutActivity.this, MainActivity.class);
170 startActivity(intent1);
171 } else {
172 CompletedPayment(); //Didn't get any documents, so continue
173 }
174 });
175 return;
176 }
177 }
178
179 String clientSecret1 = piObj.getString("client_secret");
180 PaymentIntent paymentIntent1 = mStripe.retrievePaymentIntentSynchronous(clientSecret1);
181
182 if (paymentIntent1.requiresAction()) {
183 performAction(paymentIntent1, PaymentActivity.takeawayID);
184 } else {
185 CompletedPayment();
186 }
187 } catch (APIException | AuthenticationException | InvalidRequestException | APIConnectionException | JSONException e) {
188 e.printStackTrace();
189 }
190 });
191 }, error -> {
192 Log.e(Tag, "Confirm failed: " + error.getMessage());
193 Load(true);
194 });
195 stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000,
196 DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
197 DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
198 queue.add(stringRequest);
199
200 });
201 }
202 } catch (APIException | InvalidRequestException | APIConnectionException | AuthenticationException e) {
203 e.printStackTrace();
204 }
205 });
206 }
207 }
208
209 private void handleGooglePayResult(@NonNull Intent data) {
210 final PaymentData paymentData = PaymentData.getFromIntent(data);
211 if (paymentData == null) {
212 return;
213 }
214 Log.e(Tag, "Pay Data: " + paymentData.getPaymentMethodToken());
215 Log.e(Tag, "Pay data: " + paymentData.toJson());
216
217 try {
218 JSONObject googlePaymentData = new JSONObject(paymentData.toJson());
219 Log.e(Tag, "Pay data: " + googlePaymentData.toString());
220 PaymentMethodCreateParams paymentMethodCreateParams = PaymentMethodCreateParams.createFromGooglePay(googlePaymentData);
221
222 mStripe.createPaymentMethod(paymentMethodCreateParams,
223 new ApiResultCallback<PaymentMethod>() {
224 @Override
225 public void onSuccess(@NonNull PaymentMethod result) {
226 GotCustomerKey(result);
227 }
228
229 @Override
230 public void onError(@NonNull Exception e) {
231 Load(true);
232 Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
233 }
234 });
235 } catch (JSONException ex) {
236 ex.printStackTrace();
237 }
238 }
239
240 @Override
241 public void onActivityResult(int requestCode, int resultCode,
242 @Nullable Intent data) {
243 super.onActivityResult(requestCode, resultCode, data);
244 switch (requestCode) {
245 case LOAD_PAYMENT_DATA_REQUEST_CODE: {
246 switch (resultCode) {
247 case Activity.RESULT_OK: {
248 if (data != null) {
249 Load(false);
250 handleGooglePayResult(data);
251 }
252 break;
253 }
254 case Activity.RESULT_CANCELED: {
255 Log.e(Tag, "Google pay intent cancelled");
256 break;
257 }
258 case AutoResolveHelper.RESULT_ERROR: {
259 Status status = AutoResolveHelper.getStatusFromIntent(data);
260 Log.e(Tag, status.toString());
261 // Log the status for debugging
262 // Generally there is no need to show an error to
263 // the user as the Google Payment API will do that
264 break;
265 }
266 default: {
267 // Do nothing.
268 }
269 }
270 break;
271 }
272 case PaymentMethodsActivityStarter.REQUEST_CODE: {
273 if (data == null) {
274 return;
275 }
276 final Button payButton = findViewById(R.id.payWithButton);
277 final Button changePaymentMethodButton = findViewById(R.id.changePaymentMethod);
278
279 final PaymentMethodsActivityStarter.Result result =
280 PaymentMethodsActivityStarter.Result.fromIntent(data);
281 final PaymentMethod payMethod = result != null ?
282 result.paymentMethod : null;
283
284 RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
285 final String url = "https://europe-west1-izumi-475a0.cloudfunctions.net/attachPaymentMethod?pm=" + payMethod.id + "&customer=" + payMethod.customerId;
286
287 changePaymentMethodButton.setText("Change Payment Method");
288
289 StringRequest stringRequest = new StringRequest(Request.Method.GET, url, response -> {
290 Log.e(Tag, response);
291
292 String subtitle = "Pay with " + payMethod.card.brand + " ending in " + payMethod.card.last4;
293 Log.e(Tag, subtitle);
294
295 payButton.setText(subtitle);
296 Load(true);
297 }, error -> Log.e(Tag, "Error: " + error.getMessage()));
298 stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000,
299 DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
300 DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
301 queue.add(stringRequest);
302
303 break;
304 }
305 default: {
306 // Do nothing.
307 }
308 }
309 }
310
311 void getMainPaymentCard() {
312 NetworkManager.getShared().getUser((user, error) -> {
313 if (error != null) {
314 Log.e(Tag, error.getLocalizedMessage());
315 return;
316 }
317 if (user.getCustomerID() == null) {
318 Log.e(Tag, "Couldn't get customerID");
319 return;
320 }
321 final RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
322 final String url = "https://europe-west1-izumi-475a0.cloudfunctions.net/retrievePaymentMethod?cusID=" + user.getCustomerID();
323
324 StringRequest stringRequest = new StringRequest(Request.Method.GET, url, response -> {
325 payMethod = PaymentMethod.fromString(response);
326 if (payMethod == null || payMethod.card == null || response.equals("{}")) {
327 launchWithCustomer();
328 return;
329 }
330
331 GotCustomerKey(payMethod);
332 }, httpError -> {
333
334 });
335 queue.add(stringRequest);
336 });
337 }
338
339 void GotCustomerKey(final PaymentMethod payMethod) {
340 GotCustomerKey(payMethod, false);
341 }
342
343 void GotCustomerKey(final PaymentMethod payMethod, Boolean googlePay) {
344 Log.e(Tag, "Got customer key");
345 final FirebaseFirestore fs = FirebaseFirestore.getInstance();
346 final FirebaseAuth fa = FirebaseAuth.getInstance();
347 final RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
348
349 if (!googlePay) {
350 PaymentActivity.paymentMethodString = payMethod.card.brand + " ending in " + payMethod.card.last4;
351
352 Button payButton = findViewById(R.id.payWithButton);
353 if (payButton.getText() != "Order") {
354 payButton.setText("Pay with " + PaymentActivity.paymentMethodString);
355 }
356 }
357
358 //Set parameter map
359 if (MainActivity.TableNumber == 0) {
360 //Call backend to make charge
361 HashMap<String, Object> receipt = new HashMap<>();
362 receipt.put("OwnerID", fa.getCurrentUser().getUid());
363
364 Random r = new Random();
365 int i1 = r.nextInt(1000000);
366 receipt.put("OrderName", "Order number: #" + i1);
367
368 Date currentTime = Calendar.getInstance().getTime();
369 receipt.put("TimePlaced", currentTime);
370 receipt.put("RestaurantID", MainActivity.restaurantIdentifier);
371 receipt.put("PaidAmount", PaymentActivity.PaymentAmount);
372 receipt.put("PaymentMethod", PaymentActivity.paymentMethodString);
373 //receipt.put("pi", pi.getId());
374
375 ArrayList<Order> tmpList = new ArrayList<>();
376 for (int i = 0; i < DishActivity.orderList.size(); i++) {
377 tmpList.add(DishActivity.orderList.valueAt(i));
378 }
379
380 Gson gson = new GsonBuilder().create();
381 JsonArray myCustomArray = gson.toJsonTree(tmpList).getAsJsonArray();
382
383 receipt.put("Items", myCustomArray.toString());
384 receipt.put("AcceptedTime", CheckoutActivity.ts);
385
386 fs.collection("takeaway").add(receipt).addOnCompleteListener(task -> {
387 if (!task.isSuccessful()) {
388 Log.e(Tag,task.getException().toString());
389 return;
390 }
391 final String takeawayID = task.getResult().getId();
392 RequestQueue queue1 = Volley.newRequestQueue(getApplicationContext());
393 final String url = "https://europe-west1-izumi-475a0.cloudfunctions.net/pay?email=" + fa.getCurrentUser().getEmail() + "&takeaway=" + takeawayID + "&payment_method=" + payMethod.id;
394
395 // Request a string response from the provided URL.
396 StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
397 response -> {
398 final String Response = response;
399 // retrieve the PaymentIntent on a background thread
400 AsyncTask.execute(() -> {
401 try {
402 JSONObject piObj = new JSONObject(Response);
403 if (piObj.has("error")) {
404 if (piObj.getString("error").startsWith("No users needed payment")) { //No users needed payment
405 fs.collection("orders")
406 .whereEqualTo("tableNumber", MainActivity.TableNumber)
407 .whereEqualTo("identifier", MainActivity.restaurantIdentifier)
408 .get().addOnCompleteListener(task1 -> {
409 if (!task1.isSuccessful()) {
410 Log.e(Tag, "Got the following error: ", task1.getException());
411 return;
412 }
413 List<DocumentSnapshot> docs = task1.getResult().getDocuments();
414 if (docs.size() == 0) {
415 Log.d(Tag, "Got zero documents with the information provided");
416 return;
417 }
418 boolean gotSomething = false;
419 CompleteOrderActivity.currentTableOrder.clear();
420 for (int i = 0; i < docs.size(); i++) {
421 Boolean paid = (Boolean) docs.get(i).get("Paid");
422 Long tn = (Long)docs.get(i).get("tableNumber");
423 int table = toIntExact(tn);
424 if ((paid == null || !paid) && table != 0) {
425 gotSomething = true;
426 }
427 }
428
429 if (gotSomething) {
430 Intent intent = new Intent(CheckoutActivity.this, MainActivity.class);
431 startActivity(intent);
432 } else {
433 CompletedPayment(); //Didn't get any documents, so continue
434 }
435 });
436 return;
437 }
438 Toast.makeText(getApplicationContext(), piObj.getString("error"), Toast.LENGTH_LONG).show();
439 return;
440 }
441 String clientSecret = piObj.getString("client_secret");
442
443 PaymentIntent paymentIntent = mStripe.retrievePaymentIntentSynchronous(clientSecret);
444
445 if (paymentIntent.requiresAction()) {
446 performAction(paymentIntent, takeawayID);
447 } else {
448 CompletedPayment();
449 }
450 } catch (JSONException | AuthenticationException | APIConnectionException | InvalidRequestException | APIException e) {
451 e.printStackTrace();
452 Log.e(Tag, Response);
453 }
454
455 });
456 }, error -> {
457 Log.e(Tag, "Error: That didn't work: " + error.toString());
458 Load(true);
459 });
460 stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000,
461 DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
462 DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
463 queue1.add(stringRequest);
464 });
465 } else {
466 final String url1 = "https://europe-west1-izumi-475a0.cloudfunctions.net/pay?email=" + fa.getCurrentUser().getEmail() + "&payment_method=" + payMethod.id + "&tableNumber=" + MainActivity.TableNumber + "&identifier=" + MainActivity.restaurantIdentifier;
467 Log.e(Tag, url1);
468 // Request a string response from the provided URL.
469 StringRequest stringRequest1 = new StringRequest(Request.Method.GET, url1,
470 response -> {
471 final String Response = response;
472 // retrieve the PaymentIntent on a background thread
473
474 AsyncTask.execute(() -> {
475 try {
476 JSONObject piObj = new JSONObject(Response);
477 if (piObj.has("error")) {
478 if (piObj.getString("error").startsWith("No users needed payment")) { //No users needed payment
479 fs.collection("orders")
480 .whereEqualTo("tableNumber", MainActivity.TableNumber)
481 .whereEqualTo("identifier", MainActivity.restaurantIdentifier)
482 .get().addOnCompleteListener(task -> {
483 if (!task.isSuccessful()) {
484 Log.e(Tag, "Got the following error: ", task.getException());
485 return;
486 }
487 List<DocumentSnapshot> docs = task.getResult().getDocuments();
488 if (docs.size() == 0) {
489 Log.d(Tag, "Got zero documents with the information provided");
490 return;
491 }
492 boolean gotSomething = false;
493 CompleteOrderActivity.currentTableOrder.clear();
494 for (int i = 0; i < docs.size(); i++) {
495 Boolean paid = (Boolean) docs.get(i).get("Paid");
496 Long tn = (Long)docs.get(i).get("tableNumber");
497 int table = toIntExact(tn);
498 if ((paid == null || !paid) && table != 0) {
499 gotSomething = true;
500 }
501 }
502
503 if (gotSomething) {
504 Intent intent = new Intent(CheckoutActivity.this, MainActivity.class);
505 startActivity(intent);
506 } else {
507 CompletedPayment(); //Didn't get any documents, so continue
508 }
509 });
510 return;
511 }
512 }
513 String clientSecret = piObj.getString("client_secret");
514 PaymentIntent paymentIntent = mStripe.retrievePaymentIntentSynchronous(clientSecret);
515
516 if (paymentIntent.requiresAction()) {
517 performAction(paymentIntent, "");
518 } else {
519 CompletedPayment();
520 }
521 } catch (JSONException e) {
522 Log.e(Tag, Response);
523 e.printStackTrace();
524 } catch (APIException | InvalidRequestException | APIConnectionException | AuthenticationException e) {
525 e.printStackTrace();
526 }
527
528 });
529 }, error -> {
530 Log.e(Tag, "Error: That didn't work: " + error.toString());
531 Load(true);
532 });
533 stringRequest1.setRetryPolicy(new DefaultRetryPolicy(5000,
534 DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
535 DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
536 queue.add(stringRequest1);
537 }
538
539 }
540
541 void CompletedPayment() {
542 PaymentActivity.paymentCompleted = true;
543 PaymentActivity.takeawayID = "";
544 //Successful charge, order complete:
545 Intent intent = new Intent(CheckoutActivity.this, CompleteOrderActivity.class);
546 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
547 startActivity(intent);
548 }
549
550 void performAction(PaymentIntent paymentIntent, String takeawayID) {
551 if (!takeawayID.equals("")) {
552 PaymentActivity.takeawayID = takeawayID;
553 }
554
555 mStripe.authenticatePayment(this, paymentIntent.getClientSecret());
556 }
557
558 @Override
559 protected void onCreate(Bundle savedInstanceState) {
560 super.onCreate(savedInstanceState);
561 setContentView(R.layout.activity_checkout);
562
563 if (BuildConfig.DEBUG) {
564 PaymentConfiguration.init(getApplicationContext(),"pk_test_4jMYQf3zbdTxgDqXh3OmBm9N");
565 } else {
566 PaymentConfiguration.init(getApplicationContext(),"pk_live_b9XSEcrnVpXdDBiM2hN52meS");
567 }
568 mStripe = new Stripe(this,
569 PaymentConfiguration.getInstance(getApplicationContext()).getPublishableKey());
570
571 if (BuildConfig.DEBUG) {
572 paymentsClient = Wallet.getPaymentsClient(getApplicationContext(),
573 new Wallet.WalletOptions.Builder()
574 .setEnvironment(WalletConstants.ENVIRONMENT_TEST)
575 .build());
576 } else {
577 paymentsClient = Wallet.getPaymentsClient(getApplicationContext(),
578 new Wallet.WalletOptions.Builder()
579 .setEnvironment(WalletConstants.ENVIRONMENT_PRODUCTION)
580 .build());
581 }
582
583 Toolbar toolbar = findViewById(R.id.tool_bar);
584 TextView title = toolbar.findViewById(R.id.toolbar_title);
585 title.setText("Checkout");
586
587 setSupportActionBar(toolbar);
588 getSupportActionBar().setDisplayShowTitleEnabled(false);
589 getSupportActionBar().setDisplayHomeAsUpEnabled(true);
590 getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back);
591
592 BottomNavigationView bottomNavigationView = findViewById(R.id.navigation);
593 final MenuItem acRes = bottomNavigationView.getMenu().findItem(R.id.action_restaurant);
594 acRes.setTitle(MainActivity.restaurantName);
595 bottomNavigationView.setOnNavigationItemSelectedListener(menuItem -> {
596 switch (menuItem.getItemId()) {
597 case R.id.action_order:
598 Intent orderIntent = new Intent(getApplicationContext(), PaymentActivity.class);
599 orderIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
600 startActivity(orderIntent);
601 break;
602 case R.id.action_restaurant:
603 Intent intent = new Intent(getApplicationContext(), MainActivity.class);
604 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
605 startActivity(intent);
606 break;
607 default:
608 return false;
609 }
610 return true;
611 });
612
613 TextView totalLabel = findViewById(R.id.checkoutTotal);
614 TextView taxLabel = findViewById(R.id.checkoutTax);
615 totalLabel.setText("Total: " + String.format("%.2f", (PaymentActivity.PaymentAmount)) + "kr");
616 taxLabel.setText("Tax: " + String.format("%.2f", (PaymentActivity.PaymentAmount * 0.2)) + "kr");
617
618 dpd = (DatePickerDialog) getSupportFragmentManager().findFragmentByTag("Datepickerdialog");
619 if(dpd != null) dpd.setOnDateSetListener(this);
620
621 final Button payWithButton = findViewById(R.id.payWithButton);
622 payWithButton.setOnClickListener(view -> {
623 Load(false);
624 if (MainActivity.TableNumber == 0) {
625 Calendar now = Calendar.getInstance();
626 if (dpd == null) {
627 dpd = DatePickerDialog.newInstance(
628 CheckoutActivity.this,
629 now.get(Calendar.YEAR),
630 now.get(Calendar.MONTH),
631 now.get(Calendar.DAY_OF_MONTH)
632 );
633 } else {
634 dpd.initialize(CheckoutActivity.this,
635 now.get(Calendar.YEAR),
636 now.get(Calendar.MONTH),
637 now.get(Calendar.DAY_OF_MONTH)
638 );
639 }
640 dpd.setThemeDark(false);
641 dpd.vibrate(true);
642 dpd.dismissOnPause(true);
643 dpd.showYearPickerFirst(false);
644 dpd.setVersion(DatePickerDialog.Version.VERSION_2);
645 dpd.setAccentColor(Color.parseColor("#1f2029"));
646
647 dpd.setMinDate(Calendar.getInstance());
648 Calendar cal = Calendar.getInstance();
649 cal.add(Calendar.DATE, 7);
650 dpd.setMaxDate(cal);
651 dpd.setScrollOrientation(DatePickerDialog.ScrollOrientation.VERTICAL);
652 dpd.show(getSupportFragmentManager(), "Datepickerdialog");
653 } else {
654 getMainPaymentCard();
655 }
656 });
657
658 Button changePaymentMethodButton = findViewById(R.id.changePaymentMethod);
659 changePaymentMethodButton.setOnClickListener(view -> launchWithCustomer());
660
661 Button cashButton = findViewById(R.id.cashButton);
662 cashButton.setOnClickListener(view -> {
663 Log.e(Tag,"Call a waiter");
664 Load(false);
665
666
667 NetworkManager.getShared().getUser((user, error) -> {
668 String token = String.valueOf(user.getNotificationToken());
669
670
671 // Instantiate the RequestQueue.
672 RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
673 String url ="https://izumitest.dk/restaurant/requestpayment.php?tableNumber="+MainActivity.TableNumber+"&identifier="+MainActivity.restaurantIdentifier + "&token=" + token;
674
675 // Request a string response from the provided URL.
676 StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
677 response -> Toast.makeText(getApplicationContext(), "A waiter will be at your table shortly.", Toast.LENGTH_LONG).show(), new Response.ErrorListener() {
678 @Override
679 public void onErrorResponse(VolleyError error) {
680 Log.e(Tag, "An error happened: "+error.getLocalizedMessage());
681 }
682 });
683 stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000,
684 DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
685 DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
686
687 // Add the request to the RequestQueue.
688 queue.add(stringRequest);
689 });
690 Load(true);
691 });
692
693 Button googlePayButton = findViewById(R.id.googlePayButton);
694 googlePayButton.setOnClickListener(view -> {
695 PaymentDataRequest request = createPaymentDataRequest();
696 if (request != null) {
697 AutoResolveHelper.resolveTask(
698 paymentsClient.loadPaymentData(request),
699 CheckoutActivity.this,
700 LOAD_PAYMENT_DATA_REQUEST_CODE);
701 }
702 });
703
704
705 final FirebaseFirestore fs = FirebaseFirestore.getInstance();
706 final FirebaseAuth fa = FirebaseAuth.getInstance();
707
708 Load(false);
709 NetworkManager.getShared().getUser((user, error) -> {
710 if (error != null) {
711 Log.e(Tag, error.getLocalizedMessage());
712 return;
713 }
714 if (user.getCustomerID() == null) {
715 Log.e(Tag, "Couldn't get customerid");
716 return;
717 }
718
719 final RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
720 final String url = "https://europe-west1-izumi-475a0.cloudfunctions.net/retrievePaymentMethod?cusID=" + user.getCustomerID();
721
722 StringRequest stringRequest = new StringRequest(Request.Method.GET, url, response -> {
723 Load(true);
724 payMethod = PaymentMethod.fromString(response);
725 if (payMethod != null && payMethod.card != null) {
726 payWithButton.setText("Pay with " + payMethod.card.brand + " ending in " + payMethod.card.last4);
727 } else {
728 changePaymentMethodButton.setText("Add Payment Method");
729 payWithButton.setVisibility(GONE);
730 }
731 }, httpError -> {
732 Load(true);
733 });
734 queue.add(stringRequest);
735 });
736
737 isReadyToPay();
738 }
739
740 private PaymentMethodTokenizationParameters createTokenizationParameters() {
741 return PaymentMethodTokenizationParameters.newBuilder()
742 .setPaymentMethodTokenizationType(
743 WalletConstants.PAYMENT_METHOD_TOKENIZATION_TYPE_PAYMENT_GATEWAY)
744 .addParameter("gateway", "stripe")
745 .addParameter("stripe:publishableKey",
746 "pk_test_4jMYQf3zbdTxgDqXh3OmBm9N")
747 .addParameter("stripe:version", "2018-11-08")
748 .build();
749 }
750
751 private PaymentDataRequest createPaymentDataRequest() {
752 return PaymentDataRequest.newBuilder()
753 .setTransactionInfo(
754 TransactionInfo.newBuilder()
755 .setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
756 .setTotalPrice(PaymentActivity.PaymentAmount.toString())
757 .setCurrencyCode("DKK")
758 .build())
759 .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
760 .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
761 .setCardRequirements(
762 CardRequirements.newBuilder()
763 .addAllowedCardNetworks(Arrays.asList(
764 WalletConstants.CARD_NETWORK_AMEX,
765 WalletConstants.CARD_NETWORK_DISCOVER,
766 WalletConstants.CARD_NETWORK_VISA,
767 WalletConstants.CARD_NETWORK_MASTERCARD))
768 .build())
769 .setPaymentMethodTokenizationParameters(createTokenizationParameters())
770 .build();
771 }
772
773 private void isReadyToPay() {
774 final Button googlePayButton = findViewById(R.id.googlePayButton);
775 IsReadyToPayRequest request = IsReadyToPayRequest.newBuilder()
776 .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
777 .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
778 .build();
779 paymentsClient.isReadyToPay(request).addOnCompleteListener(
780 task -> {
781 try {
782 final boolean result = task.getResult(ApiException.class);
783 if (result) {
784 googlePayButton.setVisibility(View.GONE);
785 } else {
786 // hide Google as payment option
787 googlePayButton.setVisibility(GONE);
788 }
789 } catch (ApiException exception) {
790 Log.e(Tag, exception.getLocalizedMessage());
791 }
792 }
793 );
794 }
795}