Wie behebe ich die Stripe-Zahlung für verbundene Konten?Php

PHP-Programmierer chatten hier
Guest
 Wie behebe ich die Stripe-Zahlung für verbundene Konten?

Post by Guest »

Hallo, ich habe ein Problem mit der Stripe-Zahlung vom Käufer. Ich möchte, dass der Käufer digitale Inhalte von meiner Plattform kaufen kann und wir eine Gebühr vom Käufer einbehalten. Ich möchte, dass der Kauf im Backend erfolgt. Ich verwende Stripe bei einer anderen Gelegenheit und es ist gut implementiert.

[*]Das Verkäuferkonto ist einwandfrei erstellt und der Verkäufer wird über die Stripe-Plattform verifiziert.[*]Die Zahlung vom Käufer war zunächst erfolgreich und schlug dann fehl. Wie ich Ihnen anhand meines Stripe-Test-Dashboards auf dem von mir geteilten Foto zeige, denke ich, dass die Zahlungsabsicht unvollständig ist.
[![Bildbeschreibung hier eingeben][1]][1]
< /ol>
DER CODE
FRONT-END

Code: Select all

async initializePaymentElement() {
try {
// Collect payment details
const paymentDetails = {
amount: this.fractionsToPurchase * this.pricePerFraction * 100, // Amount in smallest currency unit (e.g., cents)
currency: 'eur',
email: this.user.email, // User email
seller_connected_account_id: this.seller_connected_account_id, // Seller's Stripe account ID
};

console.log('Payment details being sent to backend:', paymentDetails);

// Call backend to create Payment Intent
const response: any = await this.userData.createPaymentIntent(paymentDetails).toPromise();

console.log('Response from backend (createPaymentIntent):', response);

if (response && response.clientSecret) {
this.clientSecret = response.clientSecret;
this.buyer_customer_id = response.customerId;

console.log('Client secret received:', this.clientSecret);
console.log('Buyer customer ID:', this.buyer_customer_id);

// Load Stripe.js and initialize payment element
if (!this.stripe) {
this.stripe = await loadStripe('your-publishable-key');
}

if (!this.stripe) {
console.error('Stripe.js failed to load');
return;
}

this.elements = this.stripe.elements({ clientSecret: this.clientSecret });
this.paymentElement = this.elements.create('payment');

// Mount Payment Element
const paymentElementContainer = document.getElementById('payment-element');
if (paymentElementContainer) {
this.paymentElement.mount(paymentElementContainer);
}

// Handle changes in the Payment Element
this.paymentElement.on('change', (event: any) => {
this.isPaymentElementFilled = event.complete;
this.paymentError = event.error ? event.error.message : null;
});
} else {
console.error('Failed to retrieve client secret or initialize Stripe.');
this.paymentError = 'Failed to retrieve payment details.';
}
} catch (error) {
console.error('Error during initializePaymentElement:', error);
this.paymentError = 'Failed to initialize payment.  Please try again.';
}
}

async purchaseMediaFractions() {
console.log("Starting purchaseMediaFractions...");

// Validate `fractionsToPurchase`
if (
this.fractionsToPurchase > this.priceDetails?.fractions ||
this.fractionsToPurchase < 1
) {
console.error("Invalid fractions:", this.fractionsToPurchase);
const toast = await this.toastController.create({
message: "Please enter a valid number of fractions to purchase.",
duration: 2000,
color: "danger",
});
await toast.present();
return;
}

const totalPrice = this.fractionsToPurchase * this.pricePerFraction;
const platformFee = totalPrice * 0.1; // 10% platform fee
const sellerEarnings = totalPrice - platformFee;

if (!this.stripe) {
console.error("Stripe instance is not initialized.");
return;
}

const elements = this.elements;
if (!elements) {
console.error("Stripe Elements are not initialized.");
return;
}

const paymentElement = this.paymentElement;
if (!paymentElement) {
console.error("Payment element is not mounted.");
return;
}

try {
// Confirm the payment with Stripe
const { error, paymentIntent } = await this.stripe.confirmPayment({
elements: this.elements,
confirmParams: {
payment_method_data: {
billing_details: {
email: this.user?.email, // Provide the buyer's email
},
},
},
redirect: "if_required", // Handle the redirect manually
});

if (error) {
console.error("Payment confirmation error:", error.message);
const toast = await this.toastController.create({
message: `Payment failed: ${error.message}`,
duration: 3000,
color: "danger",
});
await toast.present();
return;
}

if (paymentIntent?.status === "succeeded") {
console.log("Payment successful:", paymentIntent);

const toast = await this.toastController.create({
message: "Payment successful!",
duration: 3000,
color: "success",
});
await toast.present();

// Prepare purchase details for backend
const purchaseDetails = {
userId: this.user?.uid,
mediaId: this.media?.msg_id,
fractionsToPurchase: this.fractionsToPurchase,
pricePerFraction: this.pricePerFraction,
totalPrice,
platformFee,
sellerEarnings,
sellerAccountId: this.seller_connected_account_id,
buyerCustomerId: this.buyer_customer_id,
};

console.log("Purchase details:", purchaseDetails);

// Call the backend
this.userData.purchaseMediaFractions(purchaseDetails).subscribe(
async (response: any) => {
console.log("Backend response for purchaseMediaFractions:", response);

const toast = await this.toastController.create({
message: response.success ? response.message : response.error,
duration: 2000,
color: response.success ? "success" : "danger",
});
await toast.present();

if (response.success) {
console.log("Purchase completed successfully.");
this.router.navigate(["/success"]);
} else {
console.error("Purchase failed:", response.error);
}
},
async (error) => {
console.error("HTTP error in purchaseMediaFractions:", error);
const toast = await this.toastController.create({
message: "An error occurred.  Please try again later.",
duration: 2000,
color: "danger",
});
await toast.present();
}
);
} else {
console.error("Payment not completed:", paymentIntent?.status);
const toast = await this.toastController.create({
message: "Payment not completed.",
duration: 3000,
color: "warning",
});
await toast.present();
}
} catch (error) {
console.error("Error during payment process:", error);
const toast = await this.toastController.create({
message: "An error occurred during payment. Please try again later.",
duration: 3000,
color: "danger",
});
await toast.present();
}
}
Services userData

Code: Select all

createPaymentIntent(paymentDetails: any) {
const url = this.appData.getApiUrl() + 'createPaymentIntent';
const data = this.jsonToURLEncoded({
api_signature: this.api_signature,
...paymentDetails, // Spread payment details into the request body
});

console.log('Calling createPaymentIntent API:', url);
console.log('Request data:', data);

return this.http.post(url, data, { headers: this.options }).pipe(
tap((response: any) => {
console.log('createPaymentIntent API response:', response);
}),
catchError((error) => {
console.error('Error calling createPaymentIntent API:', error);
throw error;
})
);
}

purchaseMediaFractions(purchaseDetails: any) {
const url = this.appData.getApiUrl() + 'insertMediaPurchaseDetails';
const data = {
api_signature: this.api_signature,
purchaseDetails: purchaseDetails // Send as a plain object
};

return this.http.post(url, JSON.stringify(data), {
headers: this.options.set('Content-Type', 'application/json'),
});
}
UND PHP-FUNKTIONEN

Code: Select all

function createPaymentIntent() {
$request = \Slim\Slim::getInstance()->request();
$response = ['success' => false];

// Extract parameters sent from the frontend
$apiSignature = $request->post('api_signature');
$amount = intval($request->post('amount')); // Ensure amount is an integer
$currency = $request->post('currency');
$email = $request->post('email');
$sellerAccountId = $request->post('seller_connected_account_id'); // Seller's connected account ID

error_log("Received API Signature: $apiSignature, Amount: $amount, Currency: $currency, Email: $email, Seller Account ID: $sellerAccountId");

try {
// Validate parameters
if (!$amount || $amount  $email,
'description' => 'One-time customer for purchase',
]);
error_log("Stripe Customer Created: " . json_encode($customer));

$buyerCustomerId = $customer->id;
if (empty($buyerCustomerId)) {
throw new Exception("Failed to create a Stripe customer.");
}

// Calculate Platform Fee (e.g., 10%)
$applicationFeeAmount = intval($amount * 0.10); // Platform fee

// Create the PaymentIntent
$paymentIntentParams = [
'amount' => $amount, // Amount in smallest currency unit (e.g., cents)
'currency' => $currency,
'customer' => $buyerCustomerId,
'description' => 'Purchase',
'transfer_data' => [
'destination' => $sellerAccountId, // Connected seller account
],
'application_fee_amount' => $applicationFeeAmount,
];
error_log("PaymentIntent Parameters: " .  json_encode($paymentIntentParams));

$paymentIntent = \Stripe\PaymentIntent::create($paymentIntentParams);
error_log("PaymentIntent Created: " . json_encode($paymentIntent));

// Build the response with PaymentIntent details
$response = [
'success' => true,
'paymentIntentId' => $paymentIntent->id,
'clientSecret' => $paymentIntent->client_secret,
'customerId' => $buyerCustomerId,
'amount' => $amount,
'currency' => $currency,
];
} catch (\Stripe\Exception\ApiErrorException $e) {
// Stripe-specific error
error_log("Stripe API Error: " . $e->getMessage());
$response = [
'success' => false,
'error' => $e->getMessage(),
];
} catch (Exception $e) {
// General error
error_log("General Error: " . $e->getMessage());
$response = [
'success' => false,
'error' => $e->getMessage(),
];
}

// Return response as JSON
echo json_encode($response);
}

function insertMediaPurchaseDetails() {
error_log('Function Called: insertMediaPurchaseDetails');

$request = \Slim\Slim::getInstance()->request();
$data = json_decode($request->getBody(), true);
$purchaseDetails = $data['purchaseDetails'] ?? null;

error_log('Request Body: ' . $request->getBody());

// Validate purchase details
if (!$purchaseDetails || !isset($purchaseDetails['userId'], $purchaseDetails['mediaId'], $purchaseDetails['fractionsToPurchase'], $purchaseDetails['pricePerFraction'], $purchaseDetails['totalPrice'], $purchaseDetails['platformFee'], $purchaseDetails['sellerEarnings'])) {
error_log('Invalid Purchase Details: ' . print_r($purchaseDetails, true));
echo json_encode(['error' => 'Invalid purchase details provided']);
return;
}

// Log extracted values
error_log('Extracted Purchase Details: ' . print_r($purchaseDetails, true));

// Set Stripe API key
Stripe::setApiKey('sk_test_51HiSUoGozbMWFnurBqY9URXX7pEVd0Rwnm9kyyyXuOr9pKNluCdpNp522HiGN65djoplcuJcCKjiXqtFBgZoM4f000XfvRgSgi');

try {
// Create the PaymentIntent
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => intval($purchaseDetails['totalPrice'] * 100), // Amount in cents
'currency' => 'eur',
'payment_method_types' => ['card'],
'transfer_data' => [
'destination' => $purchaseDetails['sellerAccountId'],
],
]);
error_log('PaymentIntent Created: ' . json_encode($paymentIntent));

// Log PaymentIntent status
if ($paymentIntent->status !== 'succeeded') {
error_log('PaymentIntent Status: ' . $paymentIntent->status);
error_log('PaymentIntent Full Response: ' . print_r($paymentIntent, true));
echo json_encode(['error' => 'Payment failed']);
return;
}

// Proceed with database operations
$db = getDB();
$db->beginTransaction();
error_log('Database Transaction Started');

// Insert purchase details
$insertSql = "INSERT INTO media_purchases (msg_id_fk, buyer_uid_fk, fraction_count, purchase_price, total_price, platform_fee, seller_earnings, purchase_date)
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())";
$stmt = $db->prepare($insertSql);
if (!$stmt->execute([$purchaseDetails['mediaId'], $purchaseDetails['userId'], $purchaseDetails['fractionsToPurchase'], $purchaseDetails['pricePerFraction'], $purchaseDetails['totalPrice'], $purchaseDetails['platformFee'], $purchaseDetails['sellerEarnings']])) {
error_log('Failed to Insert Media Purchase: ' . json_encode($stmt->errorInfo()));
throw new Exception('Failed to insert purchase details');
}
error_log('Media Purchase Inserted Successfully');

// Commit transaction
$db->commit();
error_log('Database Transaction Committed Successfully');

echo json_encode(['success' => true, 'message' => 'Purchase completed successfully']);
} catch (\Stripe\Exception\ApiErrorException $e) {
error_log('Stripe API Error: ' .  $e->getMessage());
echo json_encode(['error' => 'Transaction failed']);
} catch (Exception $e) {
error_log('General Error: ' .  $e->getMessage());
if (isset($db) && $db->inTransaction()) {
$db->rollBack();
error_log('Database Transaction Rolled Back');
}
echo json_encode(['error' =>  'Transaction failed']);
}
}
DIE KONSOLE GIBT DIESE ZURÜCK

Code: Select all

Payment details being sent to backend: {amount: 300, currency: 'eur', email: 'pellapost@outlook.com', seller_connected_account_id: 'acct_1Qevz92eCjM0J1d3'}
user-data.ts:541 Calling createPaymentIntent API: https://project.com/api/api/createPaymentIntent
user-data.ts:542 Request data: api_signature=bcbf2fd292fa27b76d509742cdc007e2&amount=300&currency=eur&email=pellapost%40outlook.com&seller_connected_account_id=acct_1Qevz92eCjM0J1d3
user-data.ts:546 createPaymentIntent API response: {success: true, paymentIntentId: 'pi_3QgjzmGozbMWFnur0N7W0dLL', clientSecret: 'pi_3QgjzmGozbMWFnur0N7W0dLL_secret_j4J2sGD89jO3gjFgETtktYe4A', customerId: 'cus_RZtnd76eH7eIVl', amount: 300, …}
sell-details.page.ts:610 Response from backend (createPaymentIntent): {success: true, paymentIntentId: 'pi_3QgjzmGozbMWFnur0N7W0dLL', clientSecret: 'pi_3QgjzmGozbMWFnur0N7W0dLL_secret_j4J2sGD89jO3gjFgETtktYe4A', customerId: 'cus_RZtnd76eH7eIVl', amount: 300, …}
sell-details.page.ts:616 Client secret received: pi_3QgjzmGozbMWFnur0N7W0dLL_secret_j4J2sGD89jO3gjFgETtktYe4A
sell-details.page.ts:617 Buyer customer ID: cus_RZtnd76eH7eIVl

sell-details.page.ts:654 Starting purchaseMediaFractions...
sell-details.page.ts:718 Payment successful: {id: 'pi_3QgjzmGozbMWFnur0N7W0dLL', object: 'payment_intent', amount: 300, amount_details: {…}, automatic_payment_methods: {…}, …}

sell-details.page.ts:740 Purchase details: {userId: '1122', mediaId: '815', fractionsToPurchase: 3, pricePerFraction: '1.00', totalPrice: 3, …}
sell-details.page.ts:745 Backend response for purchaseMediaFractions: {error: 'Payment failed'}
sell-details.page.ts:758 Purchase failed: Payment failed
und die Fehlerprotokolle von PHP-Funktionen sind diese

Code: Select all

[13-Jan-2025 11:31:42 Europe/Athens] Received API Signature: bcbf2fd292fa27b76d509742cdc007e2, Amount: 300, Currency: eur, Email: pellapost@outlook.com, Seller Account ID: acct_1Qevz92eCjM0J1d3
[13-Jan-2025 11:31:43 Europe/Athens] Stripe Customer Created: {"id":"cus_RZtnd76eH7eIVl","object":"customer","address":null,"balance":0,"created":1736760702,"currency":null,"default_source":null,"delinquent":false,"description":"One-time customer for purchase","discount":null,"email":"pellapost@outlook.com","invoice_prefix":"2C322EAE","invoice_settings":{"custom_fields":null,"default_payment_method":null,"footer":null,"rendering_options":null},"livemode":false,"metadata":[],"name":null,"phone":null,"preferred_locales":[],"shipping":null,"tax_exempt":"none","test_clock":null}
[13-Jan-2025 11:31:43 Europe/Athens] PaymentIntent Parameters: {"amount":300,"currency":"eur","customer":"cus_RZtnd76eH7eIVl","description":"Purchase","transfer_data":{"destination":"acct_1Qevz92eCjM0J1d3"},"application_fee_amount":30}
[13-Jan-2025 11:31:43 Europe/Athens] PaymentIntent Created:  {"id":"pi_3QgjzmGozbMWFnur0N7W0dLL","object":"payment_intent","amount":300,"amount_capturable":0,"amount_details":{"tip":[]},"amount_received":0,"application":null,"application_fee_amount":30,"automatic_payment_methods":{"allow_redirects":"always","enabled":true},"canceled_at":null,"cancellation_reason":null,"capture_method":"automatic","client_secret":"pi_3QgjzmGozbMWFnur0N7W0dLL_secret_j4J2sGD89jO3gjFgETtktYe4A","confirmation_method":"automatic","created":1736760702,"currency":"eur","customer":"cus_RZtnd76eH7eIVl","description":"Purchase","invoice":null,"last_payment_error":null,"latest_charge":null,"livemode":false,"metadata":[],"next_action":null,"on_behalf_of":null,"payment_method":null,"payment_method_configuration_details":{"id":"pmc_1PgT4IGozbMWFnurJXRBOp2V","parent":null},"payment_method_options":{"bancontact":{"preferred_language":"en"},"card":{"installments":null,"mandate_options":null,"network":null,"request_three_d_secure":"automatic"},"eps":[],"giropay":[],"ideal":[],"klarna":{"preferred_locale":null},"link":{"persistent_token":null}},"payment_method_types":["card","bancontact","eps","giropay","ideal","klarna","link"],"processing":null,"receipt_email":null,"review":null,"setup_future_usage":null,"shipping":null,"source":null,"statement_descriptor":null,"statement_descriptor_suffix":null,"status":"requires_payment_method","transfer_data":{"destination":"acct_1Qevz92eCjM0J1d3"},"transfer_group":null}
[13-Jan-2025 11:32:14 Europe/Athens] Function Called: insertMediaPurchaseDetails
[13-Jan-2025 11:32:14 Europe/Athens] Request Body: {"api_signature":"bcbf2fd292fa27b76d509742cdc007e2","purchaseDetails":{"userId":"1122","mediaId":"815","fractionsToPurchase":3,"pricePerFraction":"1.00","totalPrice":3,"platformFee":0.30000000000000004,"sellerEarnings":2.7,"sellerAccountId":"acct_1Qevz92eCjM0J1d3","buyerCustomerId":"cus_RZtnd76eH7eIVl"}}
[13-Jan-2025 11:32:14 Europe/Athens] Extracted Purchase Details: Array
(
[userId] => 1122
[mediaId] => 815
[fractionsToPurchase] => 3
[pricePerFraction] => 1.00
[totalPrice] => 3
[platformFee] => 0.3
[sellerEarnings] => 2.7
[sellerAccountId] => acct_1Qevz92eCjM0J1d3
[buyerCustomerId] =>  cus_RZtnd76eH7eIVl
)

[13-Jan-2025 11:32:14 Europe/Athens] PaymentIntent Created: {"id":"pi_3Qgk0HGozbMWFnur0JDICtzQ","object":"payment_intent","amount":300,"amount_capturable":0,"amount_details":{"tip":[]},"amount_received":0,"application":null,"application_fee_amount":null,"automatic_payment_methods":null,"canceled_at":null,"cancellation_reason":null,"capture_method":"automatic","client_secret":"pi_3Qgk0HGozbMWFnur0JDICtzQ_secret_y4F4woUVuodAF2F4WANJl96Vm","confirmation_method":"automatic","created":1736760733,"currency":"eur","customer":null,"description":null,"invoice":null,"last_payment_error":null,"latest_charge":null,"livemode":false,"metadata":[],"next_action":null,"on_behalf_of":null,"payment_method":null,"payment_method_configuration_details":null,"payment_method_options":{"card":{"installments":null,"mandate_options":null,"network":null,"request_three_d_secure":"automatic"}},"payment_method_types":["card"],"processing":null,"receipt_email":null,"review":null,"setup_future_usage":null,"shipping":null,"source":null,"statement_descriptor":null,"statement_descriptor_suffix":null,"status":"requires_payment_method","transfer_data":{"destination":"acct_1Qevz92eCjM0J1d3"},"transfer_group":null}
[13-Jan-2025 11:32:14 Europe/Athens] PaymentIntent Status: requires_payment_method
[13-Jan-2025 11:32:14 Europe/Athens] PaymentIntent Full Response: Stripe\PaymentIntent Object
(
[id] => pi_3Qgk0HGozbMWFnur0JDICtzQ
[object] => payment_intent
[amount] => 300
[amount_capturable] => 0
[amount_details] => Stripe\StripeObject Object
(
[tip] => Array
(
)

)

[amount_received] => 0
[application] =>
[application_fee_amount] =>
[automatic_payment_methods] =>
[canceled_at] =>
[cancellation_reason] =>
[capture_method] => automatic
[client_secret] => pi_3Qgk0HGozbMWFnur0JDICtzQ_secret_y4F4woUVuodAF2F4WANJl96Vm
[confirmation_method] => automatic
[created] => 1736760733
[currency] => eur
[customer] =>
[description] =>
[invoice] =>
[last_payment_error] =>
[latest_charge] =>
[livemode] =>
[metadata] => Stripe\StripeObject Object
(
)

[next_action] =>
[on_behalf_of] =>
[payment_method] =>
[payment_method_configuration_details] =>
[payment_method_options] => Stripe\StripeObject Object
(
[card] => Stripe\StripeObject Object
(
[installments] =>
[mandate_options] =>
[network] =>
[request_three_d_secure] => automatic
)

)

[payment_method_types] => Array
(
[0] => card
)

[processing] =>
[receipt_email] =>
[review] =>
[setup_future_usage] =>
[shipping] =>
[source] =>
[statement_descriptor] =>
[statement_descriptor_suffix] =>
[status] => requires_payment_method
[transfer_data] => Stripe\StripeObject Object
(
[destination] => acct_1Qevz92eCjM0J1d3
)

[transfer_group] =>
)
Was mache ich falsch? Vielen Dank im Voraus
[1]: https://i.sstatic.net/DdkrgZS4.png

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post