ios - 使用带云代码的 Stripe + Parse 存储信用卡

标签 ios swift parse-platform stripe-payments parse-cloud-code

我正在尝试将用户信用卡存储到 strip 中。生成 token 后,我会尝试将用户的 token 作为客户保存到 Stripe。但是我没有找到任何问题的答案,我只需要为已经存在的用户存储一张卡。

我尝试使用 Stripe.Customers.update 方法,但如果用户有一张新卡,它会存储删除“默认”卡的新卡。并使用 Stripe.Customers.create 方法使用新卡创建新客户,但我需要存储在特定用户中。

云代码:

Parse.Cloud.define("stripeCreateCard", function(request,response)
{
    Stripe.initialize(STRIPE_SECRET_KEY);
    Stripe.Customers.create
    (
        request.params,
        {
            success:function(results)
            {
                response.success(results);
            },
            error:function(error)
            {
                response.error("Error:" +error); 
            }
        }
    );
});

Parse.Cloud.define("stripeUpdateCustomer", function(request, response) 
{
    Stripe.initialize(STRIPE_SECRET_KEY);
    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); 
            }
        }
    );
});

iOS 代码:

class func getParamsForAddingCardToCustomer(custormerId: String, cardToken: String) -> NSDictionary {
        let params = NSMutableDictionary()

        params.setObject(["card" : cardToken], forKey: "data")
        params.setObject(custormerId, forKey: "customerId")

        return params
}

var params = ParamsHelper.getParamsForAddingCardToCustomer(stripeId, cardToken: token)

PFCloud.callFunctionInBackground("stripeCreateCard", withParameters: params as [NSObject : AnyObject]) {
        (response: AnyObject?, error: NSError?) -> Void in
        let responseString = response as? String

        if (error === nil) {
            println("Response: \(responseString) ")
        }
        else if (error != nil) {
            println("Error: \(error) \(error!.userInfo)")
        }
    }

我已经尝试了几个参数来根据需要存储卡,但我总是得到错误“收到未知参数”

有人知道如何在不删除或创建新客户的情况下存储卡吗?

最佳答案

Parse 的 stripe 实现并不像它应该的那样完整。在许多情况下,您必须使用 HTTPRequest 来执行 Parse 不提供的 strip 功能。

对于这些情况,我使用以下 iOS 方法和 CloudCode 来执行我所有的 strip 化 HTTPRequest。遵循 stripe CURL API 文档进行编码非常容易。然后我构建这个方法来执行大多数 strip 化任务,IE 创建/更新/删除客户、卡片、收费等。

我首先为它提供一个方法,即 GET、POST、DELETE,具体取决于您是要检索、创建/更新还是删除 strip 对象。

然后我将可选的 pre/suf/postfixes 的组合提供给它来创建一个 url。

创建的示例 URL:

enter image description here

最后我给它参数,在创建卡并将其添加到客户的实例中,这只需要是包含 tokenID 的字典。

+(void)executeStripeCloudCodeWithMethod:(NSString *)method
                                 prefix:(NSString *)prefix
                                 suffix:(NSString *)suffix
                                postfix:(NSString *)postfix
                          secondPostfix:(NSString *)secondPostfix
                             parameters:(NSDictionary *)params
                      completionHandler:(ELStripeCompletionBlock)handler
{
    NSDictionary *parameters = @{@"method":method,
                                 @"prefix":prefix?prefix:@"",
                                 @"suffix":suffix?suffix:@"",
                                 @"postfix":postfix?postfix:@"",
                                 @"secondPostfix":secondPostfix?secondPostfix:@"",
                                 @"params":params?params:[NSNull null]
                                 };

    [PFCloud callFunctionInBackground:@"stripeHTTPRequest"
                       withParameters:parameters
                                block:^(id object, NSError *error) {
        id jsonObject;
        if (!error) {
            NSError *jsonError = nil;
            //Turn the json string into an NSDictionary
            jsonObject = [NSJSONSerialization JSONObjectWithData:[object dataUsingEncoding:NSUTF8StringEncoding]
                                                         options:kNilOptions error:&jsonError];

        }
        handler(jsonObject,error);
    }];
}

执行的云端代码:

var STRIPE_SECRET_KEY = 'sk_test_your_test_code_here';
var STRIPE_API_BASE_URL = 'api.stripe.com/v1/'
Parse.Cloud.define("stripeHTTPRequest", function(request, response) 
{
    //Check for valid pre/suf/postfixes, if they are not there do not include them.
    var prefix = request.params["prefix"];
    var suffix = "";
    var postfix = "";
    var secondPostfix = "";
    if (!isEmpty(request.params["suffix"])) suffix = '/'+request.params['suffix'];  
    if (!isEmpty(request.params["postfix"])) postfix = '/'+request.params['postfix'];   
    if (!isEmpty(request.params["secondPostfix"])) secondPostfix = '/'+request.params['secondPostfix'];

    Parse.Cloud.httpRequest(
    {
            method: request.params["method"],
            //Create URL from base url and pre/suf/postfixes
            url: 'https://'+STRIPE_API_BASE_URL + prefix + suffix + postfix + secondPostfix,
            headers: {
                'Authorization': "Bearer " + STRIPE_SECRET_KEY
            },
            params:request.params["params"],
            success: function(httpResponse) 
            {
                //response text is a json dictionary
                response.success(httpResponse.text);
            },
            error: function(httpResponse) 
            {
                response.error(httpResponse.text);
            }
    });
});

使用上面的方法,我可以创建单独的方法来执行我需要的大部分 strip 化任务。

这是一个创建新卡并将其附加到客户的示例 Stripe Card creation API

+ (void)createCardFromToken:(NSString *)tokenId customerId:(NSString *)customerId completionHandler:(ELCardCompletionBlock)handler
{

    [ELStripe executeStripeCloudCodeWithMethod:@"POST" //I use post here because we are creating a card. POST would also be used for updating a customer/card or refunding a charge for example
                                        prefix:@"customers" //If you look at the documentation and the example URL I use "customers" here as the prefix
                                        suffix:customerId //The customerID is the suffix, this will be the customer you are going to add the card to
                                       postfix:@"cards" //I believe this is "sources" now
                                 secondPostfix:nil //Not needed for this URL
                                    parameters:@{
                                                 @"card":tokenId  //Only parameter is a tokenId, and I wrap this inside an NSDictionary
                                                 }
                             completionHandler:^(id jsonObject, NSError *error) {
                                 if (error)
                                 {
                                     //Handle the error code here

                                     handler(nil,rejectError);
                                     return;
                                 }
                                 //If no error stripe returns a dictionary containing the card information. You can use this information to create a card object if so desired.
                                 handler([ELCard cardFromDictionary:jsonObject],error);
                             }];
}

关于ios - 使用带云代码的 Stripe + Parse 存储信用卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30338983/

相关文章:

ios - 如何在父 View Controller 和 subview Controller 之间传输数据

Swift 和 Parse - PFQueryTableViewController loadingViewEnabled

objective-c - Xcode 和 XIB 自文档

ios - 从表中删除 managedObject 但如何删除附加图像?

ios - 编辑另一个单元格时, Collection View 自动跳转到第一个单元格

swift - 使用 AVFoundation 和 Swift 访问多个音频硬件输出/ channel

ios - 在不使用 XCode 的情况下协同设计 iOS 应用程序(启用 APNS)

swift - RealityKit – 更改模型的颜色

用于解析云代码的类似 Node.js 的 firebase 模块

javascript - 解析云代码 全部保存