Skip to content

Card Form in PayPalWebPayments #321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: bcdc-feature
Choose a base branch
from

Conversation

KunJeongPark
Copy link
Collaborator

@KunJeongPark KunJeongPark commented Mar 19, 2025

Summary of changes

  • BCDC using existing PayPalWebPayments module instead of creating a new one
  • Add button changes for BCDC, logo image and new CardButton
  • Demo app changes to enter in card as funding source
  • Add card in PayPalWebCheckoutFundingSource enum
    this enables start function to distinguish the flows for API call (we need to get specs for)
  • UpdateClientConfig GraphQL endpoint for card fundingSource and unit tests

TODO:

  • still to verify values for API for our mobile SDK

Checklist

  • Added a changelog entry

Authors

List GitHub usernames for everyone who contributed to this pull request.

@nirvan543
Copy link
Collaborator

I like including the branded card checkout within the PayPalWebPayments module because:

  • It's a web-based payment method option and it fits with the other web-based payment method options (PayPal, Pay Later, Credit)
  • Since it's branded card processing and it's done via web, it naturally fits as an extension to the existing PayPalWebPayments module.
  • Doing it this way will reduce the amount of code we need to add (both to the SDK and demo app) and thus reduces the amount of code that the merchant has to do (and reduces their file size).
  • Since this is a short-term solution, having it as an extension to the existing module feels right.

When we build the native card fields solution, we can put it in it's own module because it will encompass BCDC, ACDC, and the other payment method options (PayPal, Pay Later, Credit, and more 👀 ).

@KunJeongPark
Copy link
Collaborator Author

KunJeongPark commented Mar 20, 2025

@nirvan543 yes i think it makes sense to have it here.
We just need to call the APi for the card funding option.

I considered having it as a separate library thinking that might be a new feature from the merchant/customer's point of view and something we could keep the same function signature for when we implement native.

I'm thinking about how we'd present this in our docs. If you want to be able to use card forms, we have guest checkout
option available through PayPalWebPayments - is that confusing?

Is it confusing for people who want to use this module for PayPal checkout flows only to see "card" value in
PayPalCheckoutFundingSource enum.

But I agree, this flow makes more sense from code perspective. As long as it doesn't cause confusion for the merchants, this definitely makes more sense.

@KunJeongPark KunJeongPark changed the base branch from main to bcdc-feature March 24, 2025 20:57

func testInit_whenCardButtonCreated_hasUIImageFromAssets() {
let sut = CardButton()
XCTAssertEqual(sut.imageView?.image, UIImage(named: "card-black"))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test, I found out is not testing what it's supposed to test on all the other buttons as well.
It just passes because both values are nil. I will make a ticket to fix these tests.

XCTAssertEqual(sut.edges, PaymentButtonEdges.softEdges)
XCTAssertEqual(sut.size, PaymentButtonSize.collapsed)
XCTAssertEqual(sut.color, PaymentButtonColor.black)
XCTAssertEqual(sut.label, PaymentButtonLabel.card)
Copy link
Collaborator Author

@KunJeongPark KunJeongPark Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this button logo doesn't have text, i defaulted it to having the label.
So collapsed and mini don't show "Debit or Credit Card" label text
Full and expanded show the label text.
All the other buttons default to collapsed, those buttons have PayPal text embedded in the logo, I'm wondering default size on the card button should be the collapsed or something else.

print("configResult: \(configResult)")
} catch {
print("error in calling graphQL: \(error.localizedDescription)")
self.notifyCheckoutFailure(with: PayPalError.payPalURLError, completion: completion)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should not return with failure. Not sure about situation where this call would fail.

@KunJeongPark KunJeongPark marked this pull request as ready for review March 25, 2025 20:32
@KunJeongPark KunJeongPark requested a review from a team as a code owner March 25, 2025 20:32
@@ -33,6 +33,17 @@ extension PayPalCreditButton.Color {
}
}

extension CardButton.Color {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: Are we able to use CaseIterable to autogenerate this code? link: docs.swift.org

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Apr 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extensions in the demo app were done that way because those enums are declared in the SDK and we can't add CaseIterable conformance from outside the module. This iteration is not something the user would do, but kind of specific to our demo app to showcase all possible button appearances

@@ -7,4 +7,5 @@ public enum HTTPHeader: String {
case authorization = "Authorization"
case contentType = "Content-Type"
case origin = "Origin"
case paypalClientContext = "paypal-client-context"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case paypalClientContext = "paypal-client-context"
case payPalClientContext = "paypal-client-context"

nit: I'm honestly back and forth on which version is best.

Comment on lines 64 to 65
"\(baseURLString)/checkoutnow?token=\(request.orderID)" +
"&fundingSource=\(request.fundingSource.rawValue)"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"\(baseURLString)/checkoutnow?token=\(request.orderID)" +
"&fundingSource=\(request.fundingSource.rawValue)"
"\(baseURLString)/checkoutnow?token=\(request.orderID)" +
"&fundingSource=\(request.fundingSource.rawValue)"

quickfix: indentation.

Copy link
Collaborator

@sshropshire sshropshire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants