Giter Club home page Giter Club logo

stripe's Issues

Better Setup Walkthrough

The README would benefit from a more in-depth setup explanation.

For example, I added the Package line, ran vapor update, regen'd the xcodeproj, and then tried the setup steps, but I don't know what to import. Tried Stripe, StripeProvider, and StripeClient to no avail. Also, I think the "Register the config and the provider to your Application" code example could be explained better. Does all of that go in app.swift? configure.swift?

Would really appreciate the additional explanation because following the current steps does not work for me. Thanks!

Unable to retrieve list of customers

Unable to retrieve a list of customers.

Error:

"error": true,
"reason": "Value required for key 'total_count'."
}```

My code is 
func index(_ req: Request) throws -> Future<StripeCustomersList> {
    let client = try req.make(StripeClient.self)
    print(client)
    return try client.customer.listAll()
}

Provide default values for all route initializers.

Currently when initializing a route service optional values don't have a default of nil and the initializer can sometimes looks like this:

try droplet.stripe?.subscriptions.create(forCustomer: "someid",
                                                     plan: plan,
                                                     applicationFeePercent: nil,
                                                     couponId: nil,
                                                     items: nil,
                                                     quantity: nil,
                                                     source: nil,
                                                     taxPercent: nil,
                                                     trialEnd: nil,
                                                     trialPeriodDays: nil,
                                                     metadata: Node(["hello":"world"]))

ideally when you only have to pass in parameters that you care about, it should look cleaner and easier to read.

try droplet.stripe?.subscriptions.create(forCustomer: "someid",
                                                     plan: plan,
                                                     metadata: Node(["hello":"world"]))

LICENSE

Hey! I am interested in including this library into my project. Since there is no license specified, may I know what's your thought on it?
I think MIT license would make sense in this case. If you want I can open a PR by adding it 👍

Nullable Source "creation" Date

I ran into this decoding error when trying to make a charge: Value required for key 'source.created'.

The code that got me there was the following:

let stripe = try req.make(StripeClient.self)

return try stripe.charge.create(amount: 1234, currency: .usd, description: "TESTING", customer: "cus_DSt0Pqu1iiiQDt").map() { charge in
    ...
}

I can fix it by changing the created var in Source.swift to an optional and its decoding line to decodeIfPresent. I'd open a PR for it but I don't have write access. Let me know how you'd like to progress. Thanks!

Make Models Parameterizable

The models don't extend Parameterizable which causes the user to have to extract each parameter individually in the request and then set them to model creation. This is very verbose.

Concrete Routes Don't Allow Optional Values

I ran into the issue of trying to create a customer with only an email and description. Normally most parameters are optional. This is true in the Model and also in the protocol for CustomerRoutes.swift. The issue lies in the fact that the implementation StripeCustomerRoutes doesn't set the optional values to = nil like the extension of the protocol. This causes the parameter to be required or else you will receive an error to the one bellow.

error: missing argument for parameter 'accountBalance' in call
            let stripeCustomer = try client.customer.create(email: customer.email, description: customer.description)
                                                            ^
                                                            accountBalance: <#Int?#>,
Stripe.CustomerRoutes:2:17: note: 'create(accountBalance:businessVatId:coupon:defaultSource:description:email:metadata:shipping:source:)' declared here

Multiple Stripe Accounts

I have a strange request, but it's a thing:

So I have a service that will charge different stripe accounts. How should the config be configured for that? We need some kind of a way to either replace the given stripe config - or to use multiple configs at the same time.

As of right now it does not look like either the Vapor-Services nor the structure of this package allow for that.

Any suggestions or ideas?

Typo in Customer.bussinessVATId

Update (2018-09-26)

The problem is actually due to a typo in Customer.bussinessVATId.

Please disregard the end of this comment.


The VAT information isn't encoded and decoded anymore.

Changes since API version 2018-05-21:

The business_vat_id field was changed from String to Hash called tax_info, consisting of tax_id and type, in both requests and responses.

Source

Additional owners: European issue

In Europe, Stripe always requires that you provide information about additional owners of the company and this is documented [here|https://stripe.com/docs/connect/updating-accounts#additional-owners]. You can have up to 4 additional owners as they need anyone owning 25% or more but you don't always have 4.

In the event of 0 additional owners the field still needs to be populated similar to the PHP library:
"additional_owners" => ""

In doing so Stripe doesn't complain about the additional owners fields being populated.

Thanks

DecodingError.keyNotFound: Value required for key 'error'.

func createCustomerId(_ req: Request) throws -> Future {

    return try req.content.decode(StripeCustomer.self).flatMap(to: StripeCustomer.self, { user in
        let response = try req.make(StripeClient.self).customer.create(email: user.email)
        return response
    })
}

}

Works perfectly, but the response is an error? Not sure where it's catching or missing a value.

Only have optional properties on models where they are truly optional.

Currently for all the stripe models all the properties are optional. This doesn't need to be the case anymore since the library is in a solid state right now. Slowly but surely we can start removing optional types from properties that are guaranteed by the API like id and object for example.

Collecting platform fees with Connect destination charges

As already discussed with @anthonycastelli and @Andrewangeta, the platform fee collection when creating destination charges is currently broken.

The documentation says that this should be achieved by simply specifying the total amount, together with destination[account] and destination[amount] where latter should be calculated by subtracting the platform’s fee from the total charge amount. No explicit "application fee" parameter is needed.

Please find my PR that fixes this issue referenced below. ✌️

Upcoming Invoice has no id

When retrieving the upcoming invoice for a customer, the decoding fails as the response does not contain an id for the upcoming invoice (the invoice does not exist yet).

I see several ways to solve that issue but they're all bad:

  • Make Invoice.id optional. (but it's inconsistent and breaks source compatibility)
  • Add a new UpcomingInvoice type. (but it's inelegant)
  • Implement init(from:) and generate a fake id if it's missing. (but We're Not Hackers!)

Does anybody have a better idea? What solution is the least bad?

Add metadata protocol to encode custom structs as part of requests.

Quoting @anthonycastelli

"One thought I had regarding metadata for Stripe is why don't we create a basic protocol, i.e.

protocol StripeMetadata: Content { }

then we can be more explicit with metadata. Right now I have a bunch of integers and optionals that I have to convert for my metadata into a string dictionary, it'd be nice to just create a struct, then populate that.

struct ChargeMetadata: StripeMetadata {
    var userName: String
    var userId: UUID
}
return charge.create(..., metadata: ChargeMetadata(userName: user.name, userId: user.id"))

At this point we could then serialize the data as part of the body data, right?"

Conform StripeError to AbortError

I have error middleware in place so that my API gets properly formatted errors. When trying to conform the StripeError to AbortError, the responses are still in the format of StripeErrors. Any insight on this?

I tried the following:

extension StripeError: AbortError {
    public var status: HTTPResponseStatus {
        return .badRequest
    }
    
    public var reason: String {
        return "because it failed..."
    }   
}

For some reason, I'm also getting status code 200 for errors..

Few bugs

try drop.addProvider(Stripe.Provider.self) - No longer works,

try StripeClient(apiKey: key).account.create(type: .standard, email: user.person.email, country: user.person.address.country, metadata: node).serializedResponse() - returns a Thread 2: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Documentation

There is a lack of documentation or started application that shows how to properly use this package.

Content-Type error from Stripe API

Hey guys,

Sorry to bother, another issue. I am getting an error response from the stripe API declaring a content-type error. Not sure what the issue is, will try and do some digging.

"Invalid request: unsupported Content-Type text/plain; charset=utf-8. If error persists and you need assistance, please contact [email protected]."

[ ERROR ] DecodingError.keyNotFound: Value required for key 'sources.data.Index 0.client_secret'

Getting the above error from the Stripe API when creating a new Customer. To the creation call, I'm passing in an email and a token source. Here's the code for the endpoint that's being hit:

func create(_ req: Request) throws -> Future<HTTPStatus> {
        return try req.content.decode(UserRequest.self).flatMap { userRequest in
            let stripeClient = try req.make(StripeClient.self)
            return try stripeClient.customer.create(email: userRequest.email, source: userRequest.stripeToken)
                .flatMap(to: HTTPStatus.self) { stripeCustomer in
                    let newUser = User(email: userRequest.email,
                                       password: userRequest.password,
                                       plate: userRequest.plate,
                                       stripeCustomerID: stripeCustomer.id)
                    return newUser.save(on: req).map { user in
                        return HTTPStatus.created
                    }
            }
        }
    }

Unable to prefill customer email when creating a checkout session

If I set the customerEmail property when creating a checkout session, I get the following error when triggering my route:

{"error":true,"reason":"Value of type 'UnkeyedDecodingContainer' required for key 'customerDetails.super'."}

Why does this happen? Based on the following information from the Stripe API docs, this should just prefill the email, no?

customer_email
optional
If provided, this value will be used when the Customer object is created. If not provided, customers will be asked to enter their email address. Use this parameter to prefill customer data if you already have an email on file. To access information about the customer once a session is complete, use the customer field.

URL query injection

When submitting a request, the query parameters are concatenated without any kind of percent encoding.

  • Values that contain + (e.g. +1 (505) 503-4455) contain spaces instead.
  • Values that contain & (e.g. Hamlin, Hamlin & McGill) are truncated.
  • An attacker may be able to add or change parameters in any request that accepts an arbitrary value submitted by the user (e.g. a valid email address).

Charges list request fails due to trailing /

When trying to retrieve a list of all charges for a customer, the network request with Stripe fails due to a trailing / in the URL. v1/charges/ is invalid and should be v1/charges.

According to the Stripe API logs,

{ "error": { "message": "Unrecognized request URL (GET: /v1/charges/). If you are trying to list objects, remove the trailing slash. If you are trying to retrieve an object, make sure you passed a valid (non-empty) identifier in your code. Please see https://stripe.com/docs or we can help at https://support.stripe.com/.", "type": "invalid_request_error" } }

[ ERROR ] DecodingError.valueNotFound - Token issue

after the payment looks successful, i am redirected to a page where i get following error.

{"error":true,"reason":"Value of type 'String' required for key 'token'."}

in the console log, i also see:

[ ERROR ] DecodingError.valueNotFound: Value of type 'String' required for key 'token'. (ErrorMiddleware.swift:26)

i launch the stripe popup via the following simple integration they explain at:

https://stripe.com/docs/checkout#integration-simple

Any idea what step I am missing at this moment?

Add webhooks support

I'm looking to add support for Webhooks. Has there been discussion on how we want to implement this?

It seems like the events use roughly the same models that we already have, just needs some parent data. I have a rough implementation already. I think we need some sort of StripeAPIResponse object to handle decoding (mainly the unix timestamps).

Should we start a new branch for this?

Replace Node in route initializers and specify a stronger type to then convert to Node

Routes only take In Nodes for collection types like JSON, Arrays of JSON, Dictionaries, Arrays etc. It's worth adding the specific type we're looking for in the parameter list and then convert it to node inside the api call. This would help make the API more easier to use and leaves out the guessing of what type the API is looking for. For example

This

create(name: String, id: String?, active: Bool?, attributes: Node?, caption: String?, deactivateOn: Node?, description: String?, images: Node?, packageDimensions: Node?, shippable: Bool?, url: String?, metadata: Node? = nil)

would become this

create(name: String, id: String?, active: Bool?, attributes: [String]?, caption: String?, deactivateOn: [String]?, description: String?, images: [String]?, packageDimensions: Node?, shippable: Bool?, url: String?, metadata: [String: Node]? = nil)

Source.type missing crash

Quite possibly I've misunderstood something as I'm very new to Stripe. I've followed the docs on Checkout and then the docs on Creating Charges and successfully retrieved my 'Strip token. I then make the following call to stripe-provider:

 return try stripeClient.charge.create(
                amount: Int(amount * 100.0),
                currency: .usd,
                source: stripeToken,
                statementDescriptor: "EFL 1 Year"
            )

According to Stripe's website the charge is successful. However, StripeSource.init crashes in the following code as type is nil.

        type = try container.decodeIfPresent(SourceType.self, forKey: .type)
        
        switch type! {
        case .card:

I've locally made the following changes and all works as expected:

        type = try container.decodeIfPresent(SourceType.self, forKey: .type)
        
        switch type {
        case .some(.card):
            card = try container.decodeIfPresent(StripeCard.self, forKey: .card)
...
            
        default: break
        }

Am I missing something in my call to cause type to be set in the response?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.