I'm currently working on integrating Stripe into my iOS application via firebase cloud functions. I'm running into a weird problem where when I try to add a card It tells me that my API key is missing when I definitely configured it in my cloud functions.
One thing I noticed is on the client side if I don't include a STPPaymentConfiguration(), then the code works correctly and a payment source gets added to firebase and stripe. Am I missing something here?
I think it's something on the front end side that I'm not quite grasping because with
let addCardViewController = STPAddCardViewController()
my code works fine and as it should but now the view controller doesn't have billing address options.
My front end swift code:
@objc func addPaymentPressed(_ sender:UIButton) {
// Setup add card view controller
let config = STPPaymentConfiguration()
config.requiredBillingAddressFields = .full
let addCardViewController = STPAddCardViewController(configuration: config, theme: theme.stpTheme)
//Creating VC without configuration and theme works just fine
//let addCardViewController = STPAddCardViewController()
addCardViewController.delegate = self
let navigationController = UINavigationController(rootViewController: addCardViewController)
navigationController.navigationBar.stp_theme = theme.stpTheme
present(navigationController, animated: true, completion: nil)
}
func addCardViewControllerDidCancel(_ addCardViewController: STPAddCardViewController) {
// Dismiss add card view controller
dismiss(animated: true)
}
func addCardViewController(_ addCardViewController: STPAddCardViewController, didCreateToken token: STPToken, completion: @escaping STPErrorBlock) {
dismiss(animated: true)
let cardObject = token.allResponseFields["card"]
print("Printing Strip Token:\(token.tokenId)")
CustomerServices.instance.addPaymentToDB(uid: currentUserId, payment_token: token.tokenId, stripe_id: token.stripeID, cardInfo: cardObject as Any) { (success) in
if success {
print("successfully added card info to subcollection!")
} else {
print("TODO: add error message handler")
}
}
}
My Cloud function code:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const stripe = require('stripe')(functions.config().stripe.token);
const currency = functions.config().stripe.currency || 'USD';
// Add a payment source (card) for a user by writing a stripe payment source token to database
exports.addPaymentSource = functions.firestore
.document('Customers/{userId}/paymentSources/{paymentId}')
.onWrite((change, context) => {
let newPaymentSource = change.after.data();
let token = newPaymentSource.payment_token;
return admin.firestore().collection("Customers").doc(`${context.params.userId}`).get()
.then((doc) => {
return doc.data().customer_id;
}).then((customer) => {
return stripe.customers.createSource(customer, {"source" : token});
});
});
When adding configuration to me STPAddCardViewController it gives me an "You did not provide an API key" error.
The issue looks to be that you are creating a new instance of STPPaymentConfiguration (which does not have your Stripe publishable key set to it), instead of using the shared instance (which you probably set your publishable key elsewhere in your code).
You need to make this change:
let config = STPPaymentConfiguration.shared()
The reason just instantiating let addCardViewController = STPAddCardViewController()
works is because the initializer actually uses STPPaymentConfiguration.shared()
for its configuration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With