简体   繁体   中英

Stripe create customer iOS

I'm using stripe and parse to allow the user of my app to enter in their credit card and purchase. I got that far the user can make a purchase everything is good. But I want to allow the user to enter their CC information and have that save so they don't have to keep re-entering it. I'm having a really hard time doing this I got the first part all figured out I just need to get this.

Update :

- (IBAction)save:(id)sender {
    if (![self.paymentView isValid]) {
        return;
    }
    if (![Stripe defaultPublishableKey]) {
        UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"No Publishable Key"
                                                          message:@"Please specify a Stripe Publishable Key in Constants.m"
                                                         delegate:nil
                                                cancelButtonTitle:NSLocalizedString(@"OK", @"OK")
                                                otherButtonTitles:nil];
        [message show];
        return;
    }
    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    STPCard *card = [[STPCard alloc] init];
    card.number = self.paymentView.card.number;
    card.expMonth = self.paymentView.card.expMonth;
    card.expYear = self.paymentView.card.expYear;
    card.cvc = self.paymentView.card.cvc;
    [Stripe createTokenWithCard:card completion:^(STPToken *token, NSError *error) {
        [MBProgressHUD hideHUDForView:self.view animated:YES];
        if (error) {
            [self hasError:error];
        } else {
           [self createCustomerFromCard:(NSString *)token completion:(PFIdResultBlock)handler]; //I'm having trouble on this line here.
        }
    }];
}
- (void)hasError:(NSError *)error {
    UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"Error")
                                                      message:[error localizedDescription]
                                                     delegate:nil
                                            cancelButtonTitle:NSLocalizedString(@"OK", @"OK")
                                            otherButtonTitles:nil];
    [message show];
}

+ (void)createCustomerFromCard:(NSString *)token completion:(PFIdResultBlock)handler
{
    [PFCloud callFunctionInBackground:@"createCustomer"
                       withParameters:@{
                                        @"tokenId":token,
                                        }
                                block:^(id object, NSError *error) {
                                    //Object is an NSDictionary that contains the stripe customer information, you can use this as is, or create an instance of your own customer class
                                    handler(object,error);
                                }];
}

So, you're doing everything right on the iOS side of things. The difference is that on your backend, you're going to want to make a Customer out of this token and then make charges against that Customer . There is a highly-relevant section on this in our documentation at https://stripe.com/docs/tutorials/charges#saving-credit-card-details-for-later .

If I were doing this, I'd create 2 Parse functions: one called createCustomer , which would take a tokenId , create a Customer with it, and return that customer's ID. You could call this in your iOS app, and then persist the customer ID locally. (You could also attach it to your User on the Parse backend. The important thing is just that you want to be able to retrieve it later). When your app user creates a token by entering their card info, you'd call this function once.

Then, any future time you want to make another charge against that credit card, you'd call a second Parse function, call it chargeCustomer . This would take the customerId that you saved previously and an amount (and, optionally, currency, etc). That's it!

Here's what those functions might look like (please note, I haven't tested this code, so there may be small errors, but it should be enough to communicate my point):

Parse.Cloud.define("createCustomer", function(request, response) {
  Stripe.Customers.create({
    card: request.params['tokenId']
  }, {
    success: function(customer) {
      response.success(customer.id);
    },
    error: function(error) {
      response.error("Error:" +error); 
    }
  })
});

Parse.Cloud.define("chargeCustomer", function(request, response) {
  Stripe.Charges.create({
    amount: request.params['amount'],
    currency: "usd",
    customer: request.params['customerId']
  }, {
    success: function(customer) {
      response.success(charge.id);
    },
    error: function(error) {
      response.error("Error:" +error); 
    }
  })
});

Hopefully that helps. If you need further assistance, feel free to contact support@stripe.com.

Jack

Step 1 Generate a Customer using Parse's API.

Step 2 Generate a Token from the CC information they enter again using Parse's API. If you need help with this, and the cloud code required let me know.

Step 3 Add a CC to a customer. I have the code below. The response back will be a Dictionary, and then I create an STPCard from the dictionary.

iOS Code:

typedef void (^STPCardCompletionBlock)(STPCard *card,NSError *error);

    +(void)addTokenId:(NSString *)tokenId toCustomerId:(NSString *)customerId completion:(STPCardCompletionBlock)handler
{
    [PFCloud callFunctionInBackground:@"stripeUpdateCustomer" withParameters:@{@"customerId":customerId,@"data":@{@"card":tokenId}} block:^(id object, NSError *error) {
        handler([[STPCard alloc]initWithAttributeDictionary:object],error);
    }];
}

Cloud Code Required:

Parse.Cloud.define("stripeUpdateCustomer", function(request, response) 
{
        Stripe.Customers.update
    (
        request.params["customerId"],
        request.params["data"],
        {
            success:function(results)
            {
                console.log(results["id"]);
                response.success(results);
            },
            error:function(error)
            {
                response.error("Error:" +error); 
            }
        }
    );
});

Here I have implemented jflinter's cloud code. Keep in mind you can include a lot more than just the tokenId to create a customer, like email, description, metadata, etc. but this just creates a customer with a card, and no other information:

+(void)createCustomerFromCard:(NSString *)tokenId completion:(PFIdResultBlock)handler
{
    [PFCloud callFunctionInBackground:@"createCustomer"
                       withParameters:@{
                                        @"tokenId":tokenId,
                                        }
                                block:^(id object, NSError *error) {
                                    //Object is an NSDictionary that contains the stripe customer information, you can use this as is, or create an instance of your own customer class
                                    handler(object,error);
    }];
}

Creating a charge using jflinter's code:

+(void)chargeCustomer:(NSString *)customerId amount:(NSNumber *)amountInCents completion:(PFIdResultBlock)handler
{
    [PFCloud callFunctionInBackground:@"chargeCustomer"
                       withParameters:@{
                                        @"amount":amountInCents,
                                        @"customerId":customerId
                                        }
                                block:^(id object, NSError *error) {
                                    //Object is an NSDictionary that contains the stripe charge information, you can use this as is or create, an instance of your own charge class.
                                    handler(object,error);

                                }];
}
@end

Correction on @jflinter 's code above. On the chargeCustomer function. replace function( customer ) with function ( charge )

Parse.Cloud.define("chargeCustomer", function(request, response) {
  Stripe.Charges.create({
    amount: request.params['amount'],
    currency: "usd",
    customer: request.params['customerId']
  }, {
    success: function(charge) {
      response.success(charge.id);
    },
    error: function(error) {
      response.error("Error:" +error); 
    }
  })
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM