Anonymous
Как получить метод оплаты на Stripe PHP
Сообщение
Anonymous » 08 июл 2024, 13:48
Здравствуйте, у меня возникли проблемы с отправкой параметра метода оплаты в функцию php (createSubscription), чтобы создать подписку на Stripe для моих пользователей.
Код: Выделить всё
import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import { Router } from "@angular/router";
import { UserData } from 'src/app/services/user-data/user-data';
import {
loadStripe,
Stripe,
StripeElements,
StripeCardElement,
StripeElementsOptions,
StripeElement,
StripeCardNumberElement,
PaymentMethod,
StripeCardElementChangeEvent,
} from '@stripe/stripe-js';
class CustomStripeCardElement {
private stripeCardElement: StripeCardElement;
paymentMethod: string | PaymentMethod;
constructor(stripeCardElement: StripeCardElement) {
this.stripeCardElement = stripeCardElement;
}
on(
eventType: 'change' | 'ready' | 'focus' | 'blur' | 'escape' | 'networkschange',
handler: (event: StripeCardElementChangeEvent | {}) => any
): void {
(this.stripeCardElement.on as any)(eventType, handler);
}
mount(selector: string): void {
this.stripeCardElement.mount(selector);
}
}
@Component({
selector: 'app-subscription',
templateUrl: 'subscription.page.html',
styleUrls: ['subscription.page.scss'],
})
export class SubscriptionPage implements AfterViewInit {
@ViewChild('paymentElement') paymentElementRef: ElementRef;
stripe: Stripe;
elements: StripeElements;
paymentElement: StripeCardElement | StripeCardNumberElement | CustomStripeCardElement;
clientSecret: string;
planId = 'price_1OPuphGozbMWFnurmxxxxxx';
customerId: any;
isPaymentElementFilled: boolean = false;
appearance: StripeElementsOptions['appearance'] = {
theme: 'stripe',
variables: {
colorPrimary: '#0570de',
colorBackground: '#ffffff',
colorText: '#30313d',
colorDanger: '#df1b41',
fontFamily: 'Ideal Sans, system-ui, sans-serif',
spacingUnit: '2px',
borderRadius: '4px',
// Define other custom styling variables as needed
},
};
menuOpenCopyright: boolean = false;
user: any = {};
email: string = '';
uid: string = '';
modalOpen: boolean = false;
cardInputFocused: boolean = false;
paymentMethod: string | PaymentMethod;
constructor(
public router: Router,
public userData: UserData,
) {
this.user = this.userData.getUserData();
this.uid = this.user.uid;
this.email = this.user.email;
this.clientSecret
}
ngAfterViewInit() {
this.userData.createCustomer(this.email).subscribe((customerResponse: any) => {
if (customerResponse.success) {
this.customerId = customerResponse.customer.id;
console.log('Customer created:', customerResponse.customer);
this.userData.createSetupIntent(this.customerId).subscribe((setupIntentResponse: any) => {
if (setupIntentResponse.success) {
this.clientSecret = setupIntentResponse.setupIntent.client_secret;
// Initialize Stripe after getting clientSecret
this.initializeStripe().then(() => {
// Once Stripe is initialized, create the payment element
this.createPaymentElement(this.clientSecret);
// Create Google Pay button after initializing Stripe
this.createGooglePayButton();
}).catch(error => {
console.error('Error initializing Stripe:', error);
});
} else {
console.error(setupIntentResponse.error);
}
});
} else {
console.error(customerResponse.error);
}
});
}
async initializeStripe() {
const stripePromise = loadStripe('pk_test_51HiSUoGozbMWFnurWW3azSXFZV47mcnH8p4MQG6HvbHuszrDPvUFYuq15TbVqZujcJNv4CSHSqkAkFm3pRk7nwoxxxxxxxx');
this.stripe = await stripePromise;
}
createPaymentElement(clientSecret) {
if (!this.stripe) {
console.error('Stripe is not initialized.');
return;
}
this.elements = this.stripe.elements({
clientSecret: clientSecret,
});
const paymentElementOptions = {
};
const stripeCardElement = this.elements.create(
'payment',
paymentElementOptions
) as unknown as StripeCardElement;
this.paymentElement = new CustomStripeCardElement(stripeCardElement);
this.paymentElement.on('change', (event: any) => {
this.isPaymentElementFilled = event.complete;
});
this.paymentElement.on('networkschange', (event: any) => {
});
this.paymentElement.mount('#payment-element');
}
async confirmPayment() {
const { setupIntent, error } = await this.stripe.confirmCardSetup(this.clientSecret, {
payment_method: {
card: this.paymentElement as StripeCardElement,
billing_details: {
email: this.email,
},
},
});
console.log('Payment Method:', setupIntent.payment_method );
if (error) {
console.error(error);
} else if (setupIntent.status === 'succeeded') {
console.log('Payment succeeded:', setupIntent);
const paymentMethod = setupIntent.payment_method;
this.paymentMethod = paymentMethod;
console.log('Payment Method:', this.paymentMethod );
this.subscribe(paymentMethod);
}
}
async subscribe(paymentMethod: string | PaymentMethod) {
const paymentMethodString = paymentMethod as string;
console.log(paymentMethodString);
this.userData.createSubscription(this.customerId, this.planId, this.clientSecret, paymentMethodString).subscribe((subscriptionResponse: any) => {
if (subscriptionResponse.success) {
console.log('Subscription successful:', subscriptionResponse.subscription);
} else {
console.error(subscriptionResponse.error);
}
});
}
службы пользовательских данных
Код: Выделить всё
createCustomer(email: string) {
const url = this.appData.getApiUrl() + 'createCustomer';
const data = this.jsonToURLEncoded({
api_signature: this.api_signature,
email: email
});
return this.http.post(url, data, { headers: this.options });
}
createSetupIntent(customerId: string) {
const url = this.appData.getApiUrl() + 'createSetupIntent';
const data = this.jsonToURLEncoded({
customerId: customerId
});
return this.http.post(url, data, { headers: this.options });
};
createSubscription(customerId: string, planId: string, clientSecret: string, paymentMethod: string) {
const url = this.appData.getApiUrl() + 'createSubscription';
const data = this.jsonToURLEncoded({
customerId: customerId,
planId: planId,
clientSecret: clientSecret,
paymentMethod: paymentMethod, // Add the paymentMethod parameter here
});
return this.http.post(url, data, { headers: this.options });
}
и функции PHP
Код: Выделить всё
function createCustomer() {
$request = \Slim\Slim::getInstance()->request();
$response['success'] = true;
$userEmail = $request->post('email');
try {
$customer = \Stripe\Customer::create([
'email' => $userEmail,
]);
$userStripeCustomerId = $customer->id;
$db = getDB();
$sql = "UPDATE users SET customer_id = :customer_id WHERE email = :email";
$stmt = $db->prepare($sql);
$stmt->bindParam(":customer_id", $userStripeCustomerId, PDO::PARAM_STR);
$stmt->bindParam(":email", $userEmail, PDO::PARAM_STR);
$stmt->execute();
$response = [
'customer' => $customer,
'success' => true,
];
} catch (\Stripe\Exception\CardException $e) {
$response = [
'error' => $e->getMessage(),
'success' => false,
];
}
echo json_encode($response);
}
function createSetupIntent() {
$request = \Slim\Slim::getInstance()->request();
$response['success'] = true;
$customerId = $request->post('customerId');
try {
$setupIntent = \Stripe\SetupIntent::create([
'customer' => $customerId,
]);
$clientSecret = $setupIntent->client_secret;
$response = [
'setupIntent' => $setupIntent,
'clientSecret' => $clientSecret,
'success' => true,
];
} catch (\Stripe\Exception\CardException $e) {
$response = [
'error' => $e->getMessage(),
'success' => false,
];
}
echo json_encode($response);
}
function createSubscription() {
$request = \Slim\Slim::getInstance()->request();
$response['success'] = true;
$customerId = $request->post('customerId');
$planId = $request->post('planId');
$paymentMethod = $request->post('paymentMethod');
try {
$subscription = \Stripe\Subscription::create([
'customer' => $customerId,
'items' => [
[
'price' => $planId,
],
],
'default_payment_method' => $paymentMethod,
]);
$response = [
'subscription' => $subscription,
'success' => true,
];
} catch (\Stripe\Exception\CardException $e) {
$response = [
'error' => $e->getMessage(),
'success' => false,
];
}
echo json_encode($response);
}
он не отправляет метод оплаты в функцию php createSubscription для полезных данных. Я получаю три отправляемых значения.
customerId: cus_QR72U2UAixxxx
planId : цена_1OPuphGozbMWFnurmxxxxxx
clientSecret: seti_1PaEoKGozbMWFnurhsTnE8O2_secret_QR72n7s1kxxxxxxxxxx
и я получаю эту ошибку Slim Application Error
Приложение не удалось запустить из-за следующей ошибки:
Код: Выделить всё
Details
Type: Stripe\Exception\InvalidRequestException
Message: This customer has no attached payment source or default payment method. Please consider adding a default payment method. For more information, visit https://stripe.com/docs/billing/subscriptions/payment-methods-setting#payment-method-priority.
File: public_html/api/vendor/stripe/stripe-php/lib/Exception/ApiErrorException.php
Line: 38
Trace
#0 public_html/api/vendor/stripe/stripe-php/lib/Exception/InvalidRequestException.php(35): Stripe\Exception\ApiErrorException::factory('This customer h...', 400, '{\n "error": {\n...', Array, Object(Stripe\Util\CaseInsensitiveArray), 'resource_missin...')
#1 /public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(189): Stripe\Exception\InvalidRequestException::factory('This customer h...', 400, '{\n "error": {\n...', Array, Object(Stripe\Util\CaseInsensitiveArray), 'resource_missin...', NULL)
#2 public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(151): Stripe\ApiRequestor::_specificAPIError('{\n "error": {\n...', 400, Object(Stripe\Util\CaseInsensitiveArray), Array, Array)
#3 public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(478): Stripe\ApiRequestor->handleErrorResponse('{\n "error": {\n...', 400, Object(Stripe\Util\CaseInsensitiveArray), Array)
#4 /public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(120): Stripe\ApiRequestor->_interpretResponse('{\n "error": {\n...', 400, Object(Stripe\Util\CaseInsensitiveArray))
#5 /public_html//api/vendor/stripe/stripe-php/lib/ApiOperations/Request.php(63): Stripe\ApiRequestor->request('post', '/v1/subscriptio...', Array, Array)
#6 public_htmlapi/vendor/stripe/stripe-php/lib/ApiOperations/Create.php(25): Stripe\ApiResource::_staticRequest('post', '/v1/subscriptio...', Array, NULL)
Клиент создан нормально, остальные функции PHP работают нормально. Я не получаю никаких других ошибок ни в консоли, ни в console.logs функций внешнего интерфейса, подтверждающих оплату или подписку, только ошибка неправильного запроса 500. Можете ли вы сказать мне, как правильно отправить способ оплаты? Или это еще одна вещь, которую мне не хватает? Спасибо
Подробнее здесь:
https://stackoverflow.com/questions/787 ... stripe-php
1720435731
Anonymous
Здравствуйте, у меня возникли проблемы с отправкой параметра метода оплаты в функцию php (createSubscription), чтобы создать подписку на Stripe для моих пользователей. [code]import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core'; import { Router } from "@angular/router"; import { UserData } from 'src/app/services/user-data/user-data'; import { loadStripe, Stripe, StripeElements, StripeCardElement, StripeElementsOptions, StripeElement, StripeCardNumberElement, PaymentMethod, StripeCardElementChangeEvent, } from '@stripe/stripe-js'; class CustomStripeCardElement { private stripeCardElement: StripeCardElement; paymentMethod: string | PaymentMethod; constructor(stripeCardElement: StripeCardElement) { this.stripeCardElement = stripeCardElement; } on( eventType: 'change' | 'ready' | 'focus' | 'blur' | 'escape' | 'networkschange', handler: (event: StripeCardElementChangeEvent | {}) => any ): void { (this.stripeCardElement.on as any)(eventType, handler); } mount(selector: string): void { this.stripeCardElement.mount(selector); } } @Component({ selector: 'app-subscription', templateUrl: 'subscription.page.html', styleUrls: ['subscription.page.scss'], }) export class SubscriptionPage implements AfterViewInit { @ViewChild('paymentElement') paymentElementRef: ElementRef; stripe: Stripe; elements: StripeElements; paymentElement: StripeCardElement | StripeCardNumberElement | CustomStripeCardElement; clientSecret: string; planId = 'price_1OPuphGozbMWFnurmxxxxxx'; customerId: any; isPaymentElementFilled: boolean = false; appearance: StripeElementsOptions['appearance'] = { theme: 'stripe', variables: { colorPrimary: '#0570de', colorBackground: '#ffffff', colorText: '#30313d', colorDanger: '#df1b41', fontFamily: 'Ideal Sans, system-ui, sans-serif', spacingUnit: '2px', borderRadius: '4px', // Define other custom styling variables as needed }, }; menuOpenCopyright: boolean = false; user: any = {}; email: string = ''; uid: string = ''; modalOpen: boolean = false; cardInputFocused: boolean = false; paymentMethod: string | PaymentMethod; constructor( public router: Router, public userData: UserData, ) { this.user = this.userData.getUserData(); this.uid = this.user.uid; this.email = this.user.email; this.clientSecret } ngAfterViewInit() { this.userData.createCustomer(this.email).subscribe((customerResponse: any) => { if (customerResponse.success) { this.customerId = customerResponse.customer.id; console.log('Customer created:', customerResponse.customer); this.userData.createSetupIntent(this.customerId).subscribe((setupIntentResponse: any) => { if (setupIntentResponse.success) { this.clientSecret = setupIntentResponse.setupIntent.client_secret; // Initialize Stripe after getting clientSecret this.initializeStripe().then(() => { // Once Stripe is initialized, create the payment element this.createPaymentElement(this.clientSecret); // Create Google Pay button after initializing Stripe this.createGooglePayButton(); }).catch(error => { console.error('Error initializing Stripe:', error); }); } else { console.error(setupIntentResponse.error); } }); } else { console.error(customerResponse.error); } }); } async initializeStripe() { const stripePromise = loadStripe('pk_test_51HiSUoGozbMWFnurWW3azSXFZV47mcnH8p4MQG6HvbHuszrDPvUFYuq15TbVqZujcJNv4CSHSqkAkFm3pRk7nwoxxxxxxxx'); this.stripe = await stripePromise; } createPaymentElement(clientSecret) { if (!this.stripe) { console.error('Stripe is not initialized.'); return; } this.elements = this.stripe.elements({ clientSecret: clientSecret, }); const paymentElementOptions = { }; const stripeCardElement = this.elements.create( 'payment', paymentElementOptions ) as unknown as StripeCardElement; this.paymentElement = new CustomStripeCardElement(stripeCardElement); this.paymentElement.on('change', (event: any) => { this.isPaymentElementFilled = event.complete; }); this.paymentElement.on('networkschange', (event: any) => { }); this.paymentElement.mount('#payment-element'); } async confirmPayment() { const { setupIntent, error } = await this.stripe.confirmCardSetup(this.clientSecret, { payment_method: { card: this.paymentElement as StripeCardElement, billing_details: { email: this.email, }, }, }); console.log('Payment Method:', setupIntent.payment_method ); if (error) { console.error(error); } else if (setupIntent.status === 'succeeded') { console.log('Payment succeeded:', setupIntent); const paymentMethod = setupIntent.payment_method; this.paymentMethod = paymentMethod; console.log('Payment Method:', this.paymentMethod ); this.subscribe(paymentMethod); } } async subscribe(paymentMethod: string | PaymentMethod) { const paymentMethodString = paymentMethod as string; console.log(paymentMethodString); this.userData.createSubscription(this.customerId, this.planId, this.clientSecret, paymentMethodString).subscribe((subscriptionResponse: any) => { if (subscriptionResponse.success) { console.log('Subscription successful:', subscriptionResponse.subscription); } else { console.error(subscriptionResponse.error); } }); } [/code] службы пользовательских данных [code]createCustomer(email: string) { const url = this.appData.getApiUrl() + 'createCustomer'; const data = this.jsonToURLEncoded({ api_signature: this.api_signature, email: email }); return this.http.post(url, data, { headers: this.options }); } createSetupIntent(customerId: string) { const url = this.appData.getApiUrl() + 'createSetupIntent'; const data = this.jsonToURLEncoded({ customerId: customerId }); return this.http.post(url, data, { headers: this.options }); }; createSubscription(customerId: string, planId: string, clientSecret: string, paymentMethod: string) { const url = this.appData.getApiUrl() + 'createSubscription'; const data = this.jsonToURLEncoded({ customerId: customerId, planId: planId, clientSecret: clientSecret, paymentMethod: paymentMethod, // Add the paymentMethod parameter here }); return this.http.post(url, data, { headers: this.options }); } [/code] и функции PHP [code]function createCustomer() { $request = \Slim\Slim::getInstance()->request(); $response['success'] = true; $userEmail = $request->post('email'); try { $customer = \Stripe\Customer::create([ 'email' => $userEmail, ]); $userStripeCustomerId = $customer->id; $db = getDB(); $sql = "UPDATE users SET customer_id = :customer_id WHERE email = :email"; $stmt = $db->prepare($sql); $stmt->bindParam(":customer_id", $userStripeCustomerId, PDO::PARAM_STR); $stmt->bindParam(":email", $userEmail, PDO::PARAM_STR); $stmt->execute(); $response = [ 'customer' => $customer, 'success' => true, ]; } catch (\Stripe\Exception\CardException $e) { $response = [ 'error' => $e->getMessage(), 'success' => false, ]; } echo json_encode($response); } function createSetupIntent() { $request = \Slim\Slim::getInstance()->request(); $response['success'] = true; $customerId = $request->post('customerId'); try { $setupIntent = \Stripe\SetupIntent::create([ 'customer' => $customerId, ]); $clientSecret = $setupIntent->client_secret; $response = [ 'setupIntent' => $setupIntent, 'clientSecret' => $clientSecret, 'success' => true, ]; } catch (\Stripe\Exception\CardException $e) { $response = [ 'error' => $e->getMessage(), 'success' => false, ]; } echo json_encode($response); } function createSubscription() { $request = \Slim\Slim::getInstance()->request(); $response['success'] = true; $customerId = $request->post('customerId'); $planId = $request->post('planId'); $paymentMethod = $request->post('paymentMethod'); try { $subscription = \Stripe\Subscription::create([ 'customer' => $customerId, 'items' => [ [ 'price' => $planId, ], ], 'default_payment_method' => $paymentMethod, ]); $response = [ 'subscription' => $subscription, 'success' => true, ]; } catch (\Stripe\Exception\CardException $e) { $response = [ 'error' => $e->getMessage(), 'success' => false, ]; } echo json_encode($response); } [/code] он не отправляет метод оплаты в функцию php createSubscription для полезных данных. Я получаю три отправляемых значения. customerId: cus_QR72U2UAixxxx planId : цена_1OPuphGozbMWFnurmxxxxxx clientSecret: seti_1PaEoKGozbMWFnurhsTnE8O2_secret_QR72n7s1kxxxxxxxxxx и я получаю эту ошибку Slim Application Error Приложение не удалось запустить из-за следующей ошибки: [code]Details Type: Stripe\Exception\InvalidRequestException Message: This customer has no attached payment source or default payment method. Please consider adding a default payment method. For more information, visit https://stripe.com/docs/billing/subscriptions/payment-methods-setting#payment-method-priority. File: public_html/api/vendor/stripe/stripe-php/lib/Exception/ApiErrorException.php Line: 38 Trace #0 public_html/api/vendor/stripe/stripe-php/lib/Exception/InvalidRequestException.php(35): Stripe\Exception\ApiErrorException::factory('This customer h...', 400, '{\n "error": {\n...', Array, Object(Stripe\Util\CaseInsensitiveArray), 'resource_missin...') #1 /public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(189): Stripe\Exception\InvalidRequestException::factory('This customer h...', 400, '{\n "error": {\n...', Array, Object(Stripe\Util\CaseInsensitiveArray), 'resource_missin...', NULL) #2 public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(151): Stripe\ApiRequestor::_specificAPIError('{\n "error": {\n...', 400, Object(Stripe\Util\CaseInsensitiveArray), Array, Array) #3 public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(478): Stripe\ApiRequestor->handleErrorResponse('{\n "error": {\n...', 400, Object(Stripe\Util\CaseInsensitiveArray), Array) #4 /public_html/api/vendor/stripe/stripe-php/lib/ApiRequestor.php(120): Stripe\ApiRequestor->_interpretResponse('{\n "error": {\n...', 400, Object(Stripe\Util\CaseInsensitiveArray)) #5 /public_html//api/vendor/stripe/stripe-php/lib/ApiOperations/Request.php(63): Stripe\ApiRequestor->request('post', '/v1/subscriptio...', Array, Array) #6 public_htmlapi/vendor/stripe/stripe-php/lib/ApiOperations/Create.php(25): Stripe\ApiResource::_staticRequest('post', '/v1/subscriptio...', Array, NULL) [/code] Клиент создан нормально, остальные функции PHP работают нормально. Я не получаю никаких других ошибок ни в консоли, ни в console.logs функций внешнего интерфейса, подтверждающих оплату или подписку, только ошибка неправильного запроса 500. Можете ли вы сказать мне, как правильно отправить способ оплаты? Или это еще одна вещь, которую мне не хватает? Спасибо Подробнее здесь: [url]https://stackoverflow.com/questions/78720403/how-to-get-paymentmethod-on-stripe-php[/url]