vapor-community / stripe-kit Goto Github PK
View Code? Open in Web Editor NEWA Swift on Server SDK for the Stripe API
License: MIT License
A Swift on Server SDK for the Stripe API
License: MIT License
new property property to add
Any idea why when I add this to my Package.swift file and run vapor xcode -y,
I get the following error:
error: the package stripekit[https://github.com/vapor-community/stripekit.git] @ 1.0.0 contains incompatible dependencies:
swift-nio-http-client[https://github.com/swift-server/swift-nio-http-client.git] @ master
Error: Could not generate Xcode project: error: the package stripekit[https://github.com/vapor-community/stripekit.git] @ 1.0.0 contains incompatible dependencies:
swift-nio-http-client[https://github.com/swift-server/swift-nio-http-client.git] @ master
Model
session model
Routes
Create session
Make all created fields non optional.
The .Net library had an issue where this was discussed and has been resolved.
For reference
This issue leads to critial bug and an app is crashed when I tried to update a subscription. Please accept PR #68.
The payloads that come through from Webhooks are slightly different than the models. For example, here's the payload from the session creation webook:
{
"id": "ID here",
"object": "event",
"api_version": "2020-03-02",
"created": 1589153882,
"data": {
"object": {
"id": "ID here",
"object": "checkout.session",
"billing_address_collection": null,
"cancel_url": "URL Here",
"client_reference_id": "Client Ref Here",
"customer": "Customer ID Here",
"customer_email": null,
"display_items": [],
"livemode": false,
"locale": null,
"metadata": {
},
"mode": "payment",
"payment_intent": "Payment Intent",
"payment_method_types": [
"card"
],
"setup_intent": null,
"shipping": null,
"shipping_address_collection": null,
"submit_type": null,
"subscription": null,
"success_url": "Success URL here"
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": null,
"idempotency_key": null
},
"type": "checkout.session.completed"
}
This almost matches the required structure for StripeSession
, but has the extra wrapper around it (i.e. root.data.object
matches StripeSession
).
For the time being I've been decoding this:
struct StripeWebhookObject: Content {
let data: DataObject
struct DataObject: Content {
let object: Object
}
struct Object: Content {
let client_reference_id: String?
let customer: String?
}
}
Which works just fine, so not urgent or anything, but it might be nice to provide webhook decodable wrappers.
Hi, I am trying to get the charge for a specific payment_intent id.
On my Vapor setup I am using:
req.stripe.charges.listAll(filter: ["payment_intent": "pi_XXXXXXXXXXXXXXXX"])
but I always get an StripeKit.StripeError and not a NIO.EventLoopFuture<StripeKit.StripeChargesList>
With curl it works like this:
curl https://api.stripe.com/v1/charges \
-u sk_test_XXXXXXXXXXXXXXXXXXXXXXXXXX: \
-d payment_intent="pi_XXXXXXXXXXXXXXXX" \
-G
Is there any documentation or help?
thx Stefan
It would be helpful if you could create a Stripe model (StripeCustomer
for example) with an initializer. Although all of the models right now are structs
, one easy way in Xcode to generate initializers is to make them classes temporarily and generate member wise initializer.
Will result in the following initializer.
Note we don't automatically get default nil values in the initializers.
This is easy but takes time is all.
Models
Credit note line item
It seems like there is a problem decoding the objects returned by stripe.connectAccounts.retrieve
.
The error I am getting is:
valueNotFound(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "super", intValue: nil)], debugDescription: "Expected Double but found null value instead.", underlyingError: nil)
But if I try curl https://api.stripe.com/v1/accounts/
the returned object is exactly as described in the Stripe documentation.
I tried to investigate the error but I was not able to find any single reference to super
in the whole stripe-kit project.
Stripe recommends as a best practice to verify the events sent via a webhook are from Stripe.
We can add signature verification via a static helper on StripeClient
StripeClient.verifySignature(....)
This parameter "requestedCapabilities" is optional in the update of account method:
https://stripe.com/docs/api/accounts/update?lang=ruby#update_account-requested_capabilities
savePaymentMethod
from PaymentIntent
APIs.unifiedProration
from InvoiceItem
APIs.plan
and quantity
from Subscription
.Stripe is returning 'fail' instead of 'failed' for StripeCardValidationCheck.
StripeKit is expecting 'failed':
But Stripe sends 'fail'. Example (/v1/payment_intents):
Documentation:
Exception:
dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "charges", intValue: nil), CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "paymentMethodDetails", intValue: nil), CodingKeys(stringValue: "card", intValue: nil), CodingKeys(stringValue: "checks", intValue: nil), CodingKeys(stringValue: "addressLine1Check", intValue: nil)], debugDescription: "Cannot initialize StripeCardValidationCheck from invalid String value fail", underlyingError: nil))
Thanks
I receive the following error in the console:
Assertion failed: file AsyncHTTPClient/HTTPClient.swift, line 117 2021-05-06 16:19:12.537202-0400 Run[9051:882865] Assertion failed: file AsyncHTTPClient/HTTPClient.swift, line 117
when running the following code:
`
func createCustomerStripe(_ req: Request) throws -> EventLoopFuture {
print("createCustomerStripe called.")
let customerFromClient = try req.content.decode(CustomersDTO.self)
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(req.eventLoop))
let stripe = StripeClient(httpClient: httpClient, eventLoop: req.eventLoop, apiKey: "test_key")
let newCustomer = stripe.customers.create(email: customerFromClient.email,
name: customerFromClient.name,
phone: customerFromClient.phone)
return newCustomer
}
`
IMPORTANT: Stripe receives each new customer when this func is called. A new customer is created with the data submitted (email, name, phone). Stripe Logs show no errors. However, Vapor crashes. Please help!
The Stripe API supports a parameter called automatic_tax that enables automatic tax collection when the Taxing Module is enabled.
Somehow this isn't something you can enable on the dashboard – you must add the parameter to Session creation to enable the feature. And I need it :D~
I'd like to create a PR where I addd a new parameter automaticTax
, similar to the same parameter in QuoteRoutes.swift
.
Implement the new prices api
let future = req.stripe.sources.attach(source: requestmodel.card_token!, customer: customer_id)
future.whenFailure { (error)
req.logger.info("(error.debugDescription)")
}
[ INFO ] Swift.DecodingError.valueNotFound(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "super", intValue: nil)], debugDescription: "Expected Double but found null value instead.", underlyingError: nil)) [request-id: EF3EEC1F-1E19-4EE3-855C-34FE32B6A49B]
Using above code to attach card to stripe customer. I am able to see card attached on stripe dashboard but getting this error.
Thank You.
The hasMore: Bool
property on lists should be optional since stripe may not include them in a response.
PR #36
Using latest Vapor 4.27.1 and NIO 2.20.2 there is a Crash with this message:
Precondition failed: file /{PATH_TO_PROJECT}/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift, line 1416
`
func createPaymentIntent(req: Request) throws -> EventLoopFuture {
guard let paymentIntentRequest: PaymentIntentRequest = try? req.content.decode(PaymentIntentRequest.self) else {
throw Abort(.notFound)
}
return req.stripe.paymentIntents.create(amount: self.calculateOrderAmount(paymentIntentRequest: paymentIntentRequest),
currency: .eur,
applicationFeeAmount: nil,
captureMethod: nil,
confirm: nil,
confirmationMethod: nil,
customer: nil,
description: nil,
errorOnRequiresAction: nil,
mandate: nil,
mandateData: nil,
metadata: nil,
offSession: nil,
onBehalfOf: nil,
paymentMethod: nil,
paymentMethodData: nil,
paymentMethodOptions: nil,
paymentMethodTypes: nil,
receiptEmail: nil,
returnUrl: nil,
savePaymentMethod: nil,
setupFutureUsage: nil,
shipping: nil,
statementDescriptor: nil,
statementDescriptorSuffix: nil,
transferData: nil,
transferGroup: nil,
useStripeSDK: nil,
expand: nil)
.map { paymentIntent in
debugPrint(paymentIntent.id)
return PaymentIntentResponse(clientSecret: paymentIntent.clientSecret)
}
}
private func calculateOrderAmount(paymentIntentRequest: PaymentIntentRequest) -> Int {
// TODO: calculate price
return 100
}
`
When attempting to retrieve a payment intent, the retrieve function gets stuck in an endless loop causing a crash
Details on the model.
https://stripe.com/docs/api/subscriptions/object#subscription_object-pending_update
This also needs to have the following events added
pending update applied
pending update expired
The following routes are effected
None
Hi everyone. I'm having trouble with my route that handles the onboarding of a user. With a POST call, I create a new Stripe Connect Account with confirmation on Stripe's logs. However, I do not receive any JSON in response to this POST. Stripe's logs show that the response is JSON with all relevant parameters attached to this new Stripe Connect Account. I have triple-checked the model that decodes the JSON. The same HTTP request made in Postman yields a response that contains email in the POST request (not JSON).
I have determined that the problem must exist on my server because 1) my client reads an error that the data received was not valid JSON, and 2) Stripe's logs show that the response to the POST is JSON.
I have attached my Vapor code below. I know that I am not implementing the proper return because whatever is being returned is not JSON. This is strange as the AccountRoutes.swift found in Stripe Kit show that the return to a create function is a StripeConnectAccount
. Thank you for the help in advance!
`func createStripeConnectAccount(_ req: Request) throws -> EventLoopFuture {
print("createStripeAccount called.")
let stripeAccountInput = try req.content.decode(AccountDTO.self)
let newStripeAccount = req.stripe.connectAccounts.create(
type: .express,
country: "US",
email: stripeAccountInput.email,
businessType: .individual,
defaultCurrency: .usd,
metadata: [
"licensePlate": stripeAccountInput.licensePlate,
"username": stripeAccountInput.username,
],
capabilities: [:]
)
return newStripeAccount
}`
Best,
Jake
Are there plans to add the new webhook events for Stripe Identity?
If there is no timeline, I can attempt to implement this and create a PR.
Usually the @Expandable
property wrapper is used to represent an id of a stripe resource as a String
or the Model specified if used with the property wrapper.
Gotta figure out a way to use the @Expandable<Model>
property wrapper for an array of Ids
@Expandable<[StripeDiscount]> public var discounts: [String]?
// Property type '[String]?' does not match that of the 'wrappedValue'
// property of its wrapper type 'Expandable<[StripeDiscount]>'
Too busy to properly address this. Will come back to it later.
API-doc
👋
I just push a very basic draft about how we could implement expandable objects.
It is a braking change so before going on I'd like to have a feedback.
You can find the diff here.
The result would be
let customer = try stripe.customers.retrieve(customer: "cus_123", expand: ["default_source"]).wait()
print(customer.defaultSource?.last4) // 4242
print(customer.$defaultSource.id) //card_1234
and
let customer = try stripe.customers.retrieve(customer: "cus_123").wait()
print(customer.defaultSource?.last4) // nil
print(customer.$defaultSource.id) //card_1234
Cheers 🍻
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.