Skip to content

Commit

Permalink
Added email field for PSCardInputView and PSCardInputLayout. Email re…
Browse files Browse the repository at this point in the history
…quire check API
  • Loading branch information
berehovyi committed Aug 11, 2022
1 parent fb36151 commit 323d51c
Show file tree
Hide file tree
Showing 21 changed files with 678 additions and 376 deletions.
2 changes: 1 addition & 1 deletion Cloudipsp.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Pod::Spec.new do |s|
s.name = "Cloudipsp"
s.version = "0.9.3"
s.version = "0.10.0"
s.summary = "Library for accepting payments directly from iOS application's clients."

s.homepage = "https://github.com/cloudipsp/ios-sdk"
Expand Down
2 changes: 2 additions & 0 deletions Cloudipsp/PSCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ typedef enum : NSUInteger {
@property (nonatomic, assign, readonly) int yy;
@property (nonatomic, strong, readonly) NSString *cvv;
@property (nonatomic, assign, readonly) PSCardType type;
@property (nonatomic, strong, readonly) NSString *email;

- (BOOL)isValidExpireMonth;
- (BOOL)isValidExpireYear;
- (BOOL)isValidExpireDate;
- (BOOL)isValidCvv;
- (BOOL)isValidCardNumber;
- (BOOL)isValidCard;
- (BOOL)isValidEmail;

+ (NSString *)getCardTypeName:(PSCardType)type;
+ (PSCardType)getCardType:(NSString *)typeName;
Expand Down
9 changes: 8 additions & 1 deletion Cloudipsp/PSCard.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ @interface PSCard ()
@property (nonatomic, assign) int yy;
@property (nonatomic, strong) NSString *cvv;
@property (nonatomic, assign) PSCardType type;
@property (nonatomic, strong) NSString *email;

@end

Expand All @@ -48,13 +49,15 @@ @implementation PSCard
+ (instancetype)cardWith:(NSString *)cardNumber
expireMm:(int)mm
expireYy:(int)yy
aCvv:(NSString *)cvv
cvv:(NSString *)cvv
email:(NSString *)email
{
PSCard * card = [[PSCard alloc] init];
card.cardNumber = cardNumber;
card.mm = mm;
card.yy = yy;
card.cvv = cvv;
card.email = email;
return card;
}

Expand Down Expand Up @@ -152,6 +155,10 @@ - (BOOL)isValidCard {
return [self isValidExpireDate] && [self isValidCvv] && [self isValidCardNumber];
}

- (BOOL)isValidEmail {
return self.email == nil || [PSUtils isValidatEmail:self.email];
}

- (PSCardType)type {
if (![self isValidCardNumber]) {
@throw [NSException exceptionWithName:@"IllegalCardNumberException" reason:@"CardNumber should be valid before for getType" userInfo:nil];
Expand Down
11 changes: 10 additions & 1 deletion Cloudipsp/PSCardInputLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,25 @@
@class PSExpMonthTextField;
@class PSExpYearTextField;
@class PSCVVTextField;
@class PSEmailTextField;
@class PSCard;
@class PSCloudipspApi;

@interface PSCardInputLayout : UIView

- (instancetype)initWithFrame:(CGRect)frame
cardNumberTextField:(PSCardNumberTextField *)cardNumberTextField
expMonthTextField:(PSExpMonthTextField *)expMonthTextField
expYearTextField:(PSExpYearTextField *)expYearTextField
cvvTextField:(PSCVVTextField *)cvvTextField;

- (instancetype)initWithFrame:(CGRect)frame
cardNumberTextField:(PSCardNumberTextField *)cardNumberTextField
expMonthTextField:(PSExpMonthTextField *)expMonthTextField
expYearTextField:(PSExpYearTextField *)expYearTextField
cvvTextField:(PSCVVTextField *)cvvTextField
emailTextField:(PSEmailTextField *)emailTextField;

- (PSCard *)confirm:(id<PSConfirmationErrorHandler>)errorHandler singleShotValidation:(BOOL)singleShotValidation;
- (PSCard *)confirm:(id<PSConfirmationErrorHandler>)errorHandler;
- (PSCard *)confirm;
Expand Down
51 changes: 43 additions & 8 deletions Cloudipsp/PSCardInputLayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "PSExpMonthTextField.h"
#import "PSExpYearTextField.h"
#import "PSCVVTextField.h"
#import "PSEmailTextField.h"

#pragma mark - PSCard

Expand All @@ -24,7 +25,8 @@ @interface PSCard (private)
+ (instancetype)cardWith:(NSString *)cardNumber
expireMm:(int)mm
expireYy:(int)yy
aCvv:(NSString *)cvv;
cvv:(NSString *)cvv
email:(NSString *)email;

@end

Expand All @@ -36,6 +38,7 @@ @interface PSCardInputLayout ()
@property (nonatomic, weak) PSExpMonthTextField *expMonthTextField;
@property (nonatomic, weak) PSExpYearTextField *expYearTextField;
@property (nonatomic, weak) PSCVVTextField *cvvTextField;
@property (nonatomic, weak) PSEmailTextField *emailTextField;
@property (nonatomic, assign) NSInteger iter;

@end
Expand All @@ -60,18 +63,36 @@ - (instancetype)initWithFrame:(CGRect)frame
}
return self;
}

- (instancetype)initWithFrame:(CGRect)frame
cardNumberTextField:(PSCardNumberTextField *)cardNumberTextField
expMonthTextField:(PSExpMonthTextField *)expMonthTextField
expYearTextField:(PSExpYearTextField *)expYearTextField
cvvTextField:(PSCVVTextField *)cvvTextField {
return [self initWithFrame:frame
cardNumberTextField:cardNumberTextField
expMonthTextField:expMonthTextField
expYearTextField:expYearTextField
cvvTextField:cvvTextField
emailTextField:nil];
}

- (instancetype)initWithFrame:(CGRect)frame
cardNumberTextField:(PSCardNumberTextField *)cardNumberTextField
expMonthTextField:(PSExpMonthTextField *)expMonthTextField
expYearTextField:(PSExpYearTextField *)expYearTextField
cvvTextField:(PSCVVTextField *)cvvTextField
emailTextField:(PSEmailTextField *)emailTextField
{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:cardNumberTextField];
[self addSubview:expMonthTextField];
[self addSubview:expYearTextField];
[self addSubview:cvvTextField];
if (emailTextField != nil) {
[self addSubview:emailTextField];
}
[self setup];
}
return self;
Expand All @@ -82,6 +103,10 @@ - (void)setup {
self.expMonthTextField = [self findOne:[PSExpMonthTextField class]];
self.expYearTextField = [self findOne:[PSExpYearTextField class]];
self.cvvTextField = [self findOne:[PSCVVTextField class]];
@try {
self.emailTextField = [self findOne:[PSEmailTextField class]];
} @catch (NSException *e) {
}
}

- (id)findOne:(Class)fieldClass {
Expand Down Expand Up @@ -118,6 +143,9 @@ - (void)clear {
self.expMonthTextField.text = @"";
self.expYearTextField.text = @"";
self.cvvTextField.text = @"";
if (self.emailTextField) {
self.emailTextField.text = @"";
}
}

- (PSCard *)confirm {
Expand All @@ -129,41 +157,44 @@ - (void)test {
case 0:
self.cardNumberTextField.text = @"4444111166665555";
self.expMonthTextField.text = @"10";
self.expYearTextField.text = @"21";
self.expYearTextField.text = @"24";
self.cvvTextField.text = @"456";
self.iter++;
break;
case 1:
self.cardNumberTextField.text = @"4444555511116666";
self.expMonthTextField.text = @"09";
self.expYearTextField.text = @"21";
self.expYearTextField.text = @"24";
self.cvvTextField.text = @"789";
self.iter++;
break;
case 2:
self.cardNumberTextField.text = @"4444111155556666";
self.expMonthTextField.text = @"08";
self.expYearTextField.text = @"21";
self.expYearTextField.text = @"24";
self.cvvTextField.text = @"149";
self.iter++;
break;
case 3:
self.cardNumberTextField.text = @"4444555566661111";
self.expMonthTextField.text = @"11";
self.expYearTextField.text = @"22";
self.expYearTextField.text = @"24";
self.cvvTextField.text = @"123";
self.iter++;
break;
case 4:
self.cardNumberTextField.text = @"378282246310005";
self.expMonthTextField.text = @"11";
self.expYearTextField.text = @"23";
self.expYearTextField.text = @"24";
self.cvvTextField.text = @"123";
self.iter = 0;
break;
default:
break;
}
if (self.emailTextField != nil) {
self.emailTextField.text = @"[email protected]";
}
}

- (PSCard *)confirm:(id<PSConfirmationErrorHandler>)errorHandler {
Expand All @@ -175,14 +206,18 @@ - (PSCard *)confirm:(id<PSConfirmationErrorHandler>)errorHandler singleShotValid
[errorHandler onCardInputErrorClear:self aTextField:self.expMonthTextField];
[errorHandler onCardInputErrorClear:self aTextField:self.expYearTextField];
[errorHandler onCardInputErrorClear:self aTextField:self.cvvTextField];
if (self.emailTextField != nil) {
[errorHandler onCardInputErrorClear:self aTextField:self.emailTextField];
}

NSCharacterSet *validationSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSString *cardNumber = [NSMutableString stringWithString:[[self.cardNumberTextField.text componentsSeparatedByCharactersInSet:validationSet] componentsJoinedByString:@""]];

PSCard *card = [PSCard cardWith:cardNumber
expireMm:[self.expMonthTextField.text intValue]
expireYy:[self.expYearTextField.text intValue]
aCvv:self.cvvTextField.text];
cvv:self.cvvTextField.text
email:self.emailTextField == nil ? nil : self.emailTextField.text];

BOOL cardValidated = YES;
if (![card isValidCardNumber]) {
Expand Down
6 changes: 6 additions & 0 deletions Cloudipsp/PSCardInputView.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

@class PSCardNumberTextField;
@class PSCard;
@class PSCloudipspApi;

@interface PSCardInputView : UIView

Expand All @@ -33,11 +34,16 @@
@property (nonatomic, strong) IBOutlet UIView *view;
@property (nonatomic, weak) IBOutlet id<PSCardInputViewDelegate> inputDelegate;

- (void)adaptForApi:(PSCloudipspApi *)api
andCurrency:(NSString *)currency;
- (void)adaptForApi:(PSCloudipspApi *)api
andToken:(NSString *)token;

- (PSCard *)confirm:(id<PSConfirmationErrorHandler>)errorHandler singleShotValidation:(BOOL)singleShotValidation;
- (PSCard *)confirm:(id<PSConfirmationErrorHandler>)errorHandler;
- (PSCard *)confirm;
- (void)clear;
- (void)test;
- (void)setEmailVisibility:(BOOL)visible;

@end
60 changes: 59 additions & 1 deletion Cloudipsp/PSCardInputView.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#import "PSExpMonthTextField.h"
#import "PSExpYearTextField.h"
#import "PSCVVTextField.h"
#import "PSEmailTextField.h"
#import "PSCardInputLayout.h"
#import "PSCardInputView.h"

Expand All @@ -33,25 +34,62 @@ + (instancetype)cardWith:(NSString *)cardNumber

@interface PSCardInputView ()



@property (strong, nonatomic) IBOutletCollection(UITextField) NSArray *fields;
@property (nonatomic, strong) IBOutlet UILabel *cardNumberLabel;
@property (nonatomic, strong) IBOutlet UILabel *expiryLabel;
@property (nonatomic, strong) IBOutlet UILabel *cvvLabel;
@property (strong, nonatomic) IBOutlet UILabel *emailLabel;
@property (strong, nonatomic) IBOutlet PSEmailTextField *emailTextInput;
@property (nonatomic, weak) IBOutlet PSCardInputLayout *cardInputLayout;
@property (strong, nonnull) NSArray<NSLayoutConstraint *> *emailConstraints;

@property (nonatomic, assign) NSInteger iter;

@end

@implementation PSCardInputView

- (void)setupView {
self.emailConstraints = @[];
self.translatesAutoresizingMaskIntoConstraints = NO;
[[[NSBundle bundleForClass:[PSCardInputView class]] loadNibNamed:@"PSCardInputView" owner:self options:nil] firstObject];
[self.view setFrame:self.bounds];
[self setUpLocalization:[PSCloudipspApi getLocalization]];
[self addSubview:self.view];
}

-(void)setEmailVisibility:(BOOL)visible {
if (self.emailConstraints) {
[NSLayoutConstraint deactivateConstraints:self.emailConstraints];
}

if (visible) {
[self.cardInputLayout addSubview:self.emailLabel];
[self.cardInputLayout addSubview:self.emailTextInput];

self.emailConstraints = @[
[self.emailLabel.leadingAnchor constraintEqualToAnchor:self.cardInputLayout.leadingAnchor constant:20.0f],
[self.emailLabel.trailingAnchor constraintEqualToAnchor:self.cardInputLayout.trailingAnchor constant:20.0f],
[self.emailLabel.topAnchor constraintEqualToAnchor:self.cvvTextField.bottomAnchor constant:8.0f],

[self.emailTextInput.leadingAnchor constraintEqualToAnchor:self.cardInputLayout.leadingAnchor constant:20.0f],
[self.emailTextInput.trailingAnchor constraintEqualToAnchor:self.cardInputLayout.trailingAnchor constant:20.0f],
[self.emailTextInput.topAnchor constraintEqualToAnchor:self.emailLabel.bottomAnchor constant:8.0f],


[self.cardInputLayout.bottomAnchor constraintEqualToAnchor:self.emailTextInput.bottomAnchor]
];
} else {
[self.emailLabel removeFromSuperview];
[self.emailTextInput removeFromSuperview];
self.emailConstraints = @[
[self.cardInputLayout.bottomAnchor constraintEqualToAnchor:self.cvvTextField.bottomAnchor]
];
}
[NSLayoutConstraint activateConstraints:self.emailConstraints];
}

- (void)setUpLocalization:(PSLocalization *)localization {
self.cardNumberLabel.text = localization.cardNumber;
self.expiryLabel.text = localization.expiry;
Expand Down Expand Up @@ -79,6 +117,25 @@ - (instancetype)initWithFrame:(CGRect)frame
return self;
}

- (void)adaptForApi:(PSCloudipspApi *)api
andCurrency:(NSString *)currency {
[api isPayerEmailRequiredForCurrency:currency withCallback:^(BOOL isRequired, NSError *error) {
if (error) {
return;
}
[self setEmailVisibility:isRequired];
}];
}
- (void)adaptForApi:(PSCloudipspApi *)api
andToken:(NSString *)token {
[api isPayerEmailRequiredForToken:token withCallback:^(BOOL isRequired, NSError *error) {
if (error) {
return;
}
[self setEmailVisibility:isRequired];
}];
}

- (void)clear {
[self.cardInputLayout clear];
}
Expand All @@ -87,6 +144,7 @@ - (PSCard *)confirm {
return [self.cardInputLayout confirm:[[PSDefaultConfirmationErrorHandler alloc] init]];
}


- (void)test {
[self.cardInputLayout test];
}
Expand Down
Loading

0 comments on commit 323d51c

Please sign in to comment.