Skip to content
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

Add on_behalf_of to CardField #1750

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
**Features**

- Adds support for CustomerSession in private beta [1744](https://github.com/stripe/stripe-react-native/pull/1744)
- Added `onBehalfOf` prop to CardField

**Fixes**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ class CardFieldView(context: ThemedReactContext) : FrameLayout(context) {
mCardWidget.setPreferredNetworks(mapToPreferredNetworks(preferredNetworks))
}

fun setOnBehalfOf(onBehalfOf: String?) {
mCardWidget.onBehalfOf = onBehalfOf
}

/**
* We can reliable assume that setPostalCodeEnabled is called before
* setCountryCode because of the order of the props in CardField.tsx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ class CardFieldViewManager : SimpleViewManager<CardFieldView>() {
view.setCountryCode(countryCode)
}

@ReactProp(name = "onBehalfOf")
fun setOnBehalfOf(view: CardFieldView, onBehalfOf: String?) {
view.setOnBehalfOf(onBehalfOf)
}

@ReactProp(name = "placeholders")
fun setPlaceHolders(view: CardFieldView, placeholders: ReadableMap) {
view.setPlaceHolders(placeholders)
Expand Down
1 change: 1 addition & 0 deletions ios/CardFieldManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ @interface RCT_EXTERN_MODULE(CardFieldManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(autofocus, BOOL)
RCT_EXPORT_VIEW_PROPERTY(disabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(dangerouslyGetFullCardDetails, BOOL)
RCT_EXPORT_VIEW_PROPERTY(onBehalfOf, NSString)
RCT_EXPORT_VIEW_PROPERTY(preferredNetworks, NSArray)
RCT_EXTERN_METHOD(focus:(nonnull NSNumber*) reactTag)
RCT_EXTERN_METHOD(blur:(nonnull NSNumber*) reactTag)
Expand Down
60 changes: 33 additions & 27 deletions ios/CardFieldView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
@objc var onCardChange: RCTDirectEventBlock?
@objc var onFocusChange: RCTDirectEventBlock?
@objc var dangerouslyGetFullCardDetails: Bool = false

private var cardField = STPPaymentCardTextField()

public var cardParams: STPPaymentMethodParams? = nil
public var cardPostalCode: String? = nil

Expand All @@ -17,27 +17,33 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
cardField.isUserInteractionEnabled = !disabled
}
}

@objc var postalCodeEnabled: Bool = true {
didSet {
cardField.postalCodeEntryEnabled = postalCodeEnabled
}
}

@objc var countryCode: String? {
didSet {
cardField.countryCode = countryCode
}
}


@objc var onBehalfOf: String? {
didSet {
cardField.onBehalfOf = onBehalfOf
}
}

@objc var preferredNetworks: Array<Int>? {
didSet {
if let preferredNetworks = preferredNetworks {
cardField.preferredNetworks = preferredNetworks.map(Mappers.intToCardBrand).compactMap { $0 }
}
}
}

@objc var placeholders: NSDictionary = NSDictionary() {
didSet {
if let numberPlaceholder = placeholders["number"] as? String {
Expand All @@ -56,15 +62,15 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
}
}
}

@objc var autofocus: Bool = false {
didSet {
if autofocus == true {
cardField.reactFocus()
}
}
}

@objc var cardStyle: NSDictionary = NSDictionary() {
didSet {
if let borderWidth = cardStyle["borderWidth"] as? Int {
Expand All @@ -91,7 +97,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
cardField.textErrorColor = UIColor(hexString: textErrorColor)
}
let fontSize = cardStyle["fontSize"] as? Int ?? 14

if let fontFamily = cardStyle["fontFamily"] as? String {
cardField.font = UIFont(name: fontFamily, size: CGFloat(fontSize)) ?? UIFont.systemFont(ofSize: CGFloat(fontSize))
} else {
Expand All @@ -104,46 +110,46 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
}
}
}

override init(frame: CGRect) {
super.init(frame: frame)
cardField.delegate = self

self.addSubview(cardField)
}

func focus() {
cardField.becomeFirstResponder()
}

func blur() {
cardField.resignFirstResponder()
}

func clear() {
cardField.clear()
}

func paymentCardTextFieldDidEndEditing(_ textField: STPPaymentCardTextField) {
onFocusChange?(["focusedField": NSNull()])
}

func paymentCardTextFieldDidBeginEditingNumber(_ textField: STPPaymentCardTextField) {
onFocusChange?(["focusedField": "CardNumber"])
}

func paymentCardTextFieldDidBeginEditingCVC(_ textField: STPPaymentCardTextField) {
onFocusChange?(["focusedField": "Cvc"])
}

func paymentCardTextFieldDidBeginEditingExpiration(_ textField: STPPaymentCardTextField) {
onFocusChange?(["focusedField": "ExpiryDate"])
}

func paymentCardTextFieldDidBeginEditingPostalCode(_ textField: STPPaymentCardTextField) {
onFocusChange?(["focusedField": "PostalCode"])
}

func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) {
if onCardChange != nil {
let brand = STPCardValidator.brand(forNumber: textField.cardNumber ?? "")
Expand Down Expand Up @@ -180,29 +186,29 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
self.cardPostalCode = nil
}
}

override func layoutSubviews() {
cardField.frame = self.bounds
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func paymentContext(_ paymentContext: STPPaymentContext, didFailToLoadWithError error: Error) {
//
}

func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
//
}

func paymentContext(_ paymentContext: STPPaymentContext, didCreatePaymentResult paymentResult: STPPaymentResult, completion: @escaping STPPaymentStatusBlock) {
//
}

func paymentContext(_ paymentContext: STPPaymentContext, didFinishWith status: STPPaymentStatus, error: Error?) {
//
}

}
1 change: 1 addition & 0 deletions ios/CardFormManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ @interface RCT_EXTERN_MODULE(CardFormManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(cardStyle, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(disabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(preferredNetworks, NSArray)
RCT_EXPORT_VIEW_PROPERTY(onBehalfOf, NSString)
RCT_EXTERN_METHOD(focus:(nonnull NSNumber*) reactTag)
RCT_EXTERN_METHOD(blur:(nonnull NSNumber*) reactTag)
@end
2 changes: 2 additions & 0 deletions src/components/CardField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export interface Props extends AccessibilityProps {
/** The list of preferred networks that should be used to process payments made with a co-branded card.
* This value will only be used if your user hasn't selected a network themselves. */
preferredNetworks?: Array<CardBrand>;
/** The account (if any) for which the funds of the intent are intended. */
onBehalfOf?: string;
/**
* WARNING: If set to `true` the full card number will be returned in the `onCardChange` handler.
* Only do this if you're certain that you fulfill the necessary PCI compliance requirements.
Expand Down
Loading