diff --git a/includes/Builder/Methods/PayPal/PayPal.php b/includes/Builder/Methods/PayPal/PayPal.php index b2bc0f8..55e3f2b 100644 --- a/includes/Builder/Methods/PayPal/PayPal.php +++ b/includes/Builder/Methods/PayPal/PayPal.php @@ -125,7 +125,7 @@ public function makePayment($transactionId, $entryId, $form_data) 'email' => $supporter->supporters_email, 'no_shipping' => '1', 'no_note' => '1', - 'currency_code' => $supporter->currency ? $supporter->currency : 'USD', + 'currency_code' => $supporter->currency ?? 'USD', 'charset' => 'UTF-8', 'custom' => $transactionId, 'return' => $this->successUrl($supporter), @@ -301,11 +301,14 @@ public function render($template) ?> 'Bearer ' . $stripeApiKey, + 'Content-Type' => 'application/x-www-form-urlencoded', + ); + + $requestData = array( + 'headers' => $sessionHeaders, + 'body' => http_build_query($data), + 'method' => $method, + ); + + $url = $this->apiUrl . $path; + + $sessionResponse = wp_remote_post($url, $requestData); + + if (is_wp_error($sessionResponse)) { + echo "API Error: " . esc_html($sessionResponse->get_error_message()); + exit; + } + + $sessionResponseData = wp_remote_retrieve_body($sessionResponse); + + $sessionData = json_decode($sessionResponseData, true); + + if (empty($sessionData['id'])) { + $message = Arr::get($sessionData, 'detail'); + if (!$message) { + $message = Arr::get($sessionData, 'error.message'); + } + if (!$message) { + $message = 'Unknown Stripe API request error'; + } + + return new \WP_Error(423, $message, $sessionData); + } + + return $sessionData; + } + + + public function verifyIPN() + { + if (!isset($_REQUEST['wpm_bmc_stripe_listener'])) { + return; + } + + $post_data = ''; + if (ini_get('allow_url_fopen')) { + $post_data = file_get_contents('php://input'); + } else { + // If allow_url_fopen is not enabled, then make sure that post_max_size is large enough + ini_set('post_max_size', '12M'); + } + + $data = json_decode($post_data); + + if ($data->id) { + status_header(200); + return $data; + } else { + error_log("specific event"); + error_log(print_r($data)); + return false; + } + + exit(200); + } + + public function getInvoice($eventId) + { + $api = new ApiRequest(); + $api::set_secret_key((new StripeSettings())->getApiKey()); + return $api::request([], 'events/' . $eventId, 'GET'); + } +} diff --git a/includes/Builder/Methods/Stripe/Stripe.php b/includes/Builder/Methods/Stripe/Stripe.php index b5f1148..7c1d777 100644 --- a/includes/Builder/Methods/Stripe/Stripe.php +++ b/includes/Builder/Methods/Stripe/Stripe.php @@ -4,6 +4,8 @@ use BuyMeCoffee\Builder\Methods\BaseMethods; use BuyMeCoffee\Classes\Vite; +use BuyMeCoffee\Models\Supporters; +use BuyMeCoffee\Models\Transactions; class Stripe extends BaseMethods { @@ -21,9 +23,79 @@ public function __construct() public function makePayment($transactionId, $entryId, $form_data) { - // TO-Do will implement later on upcoming version + $transactionModel = new Transactions(); + $transaction = $transactionModel->find($transactionId); + + $supportersModel = new Supporters(); + $supporter = $supportersModel->find($entryId); + $hash = $transaction->entry_hash; + + $keys = StripeSettings::getKeys(); + $apiKey = $keys['secret']; + + $paymentArgs = array( + 'payment_method_type' => ['card'], + 'client_reference_id' => $hash, + 'amount' => (int) round($transaction->payment_total, 0), + 'currency' => strtolower($transaction->currency), + 'description' => "Buy coffee from {$supporter->supporters_name}", + 'customer_email' => $supporter->supporters_email, + 'success_url' => $this->successUrl($supporter), + 'public_key' => $keys['public'] + ); + + $this->handleInlinePayment($transaction, $paymentArgs, $apiKey); + } + + public function handleInlinePayment($transaction, $paymentArgs, $apiKey) + { + try { + $intentData = $this->intentData($paymentArgs); + $invoiceResponse = (new API())->makeRequest('payment_intents', $intentData, $apiKey, 'POST'); + + $transaction->payment_args = $paymentArgs; + + $responseData = [ + 'nextAction' => 'stripe', + 'actionName' => 'custom', + 'buttonState' => 'hide', + 'intent' => $invoiceResponse, + 'order_items' => $transaction, + 'message_to_show' => __('Payment Modal is opening, Please complete the payment', 'buy-me-coffee'), + ]; + + wp_send_json_success($responseData, 200); + } catch (\Exception $e) { + wp_send_json_error([ + 'status' => 'failed', + 'message' => $e->getMessage() + ], 423); + } } + public function intentData($args) + { + $sessionPayload = array( + 'amount' => $args['amount'], + 'currency' => $args['currency'], + 'metadata' => [ + 'ref_id' => $args['client_reference_id'], + ], + ); + + return $sessionPayload; + } + public function successUrl($supporter) + { + return add_query_arg(array( + 'send_coffee' => '', + 'wpm_bmc_success' => 1, + 'hash' => $supporter->entry_hash, + 'payment_method' => 'stripe' + ), home_url()); + } + + public function sanitize($settings) { foreach ($settings as $key => $value) { @@ -55,18 +127,27 @@ public function getSettings() return wp_parse_args($settings, $defaults); } + public function maybeLoadModalScript() + { + //phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion + wp_enqueue_script('wpm-buymecoffee-checkout-sdk-' . $this->method, 'https://js.stripe.com/v3/',null, false); + Vite::enqueueScript('wpm-buymecoffee-checkout-handler-' . $this->method, 'js/PaymentMethods/stripe-checkout.js', ['wpm-buymecoffee-checkout-sdk-stripe', 'jquery'], '1.0.1', false); + } + public function render($template) { + $this->maybeLoadModalScript(); + ?> 'no', + 'payment_mode' => 'test', + 'live_pub_key' => '', + 'live_secret_key' => '', + 'test_pub_key' => '', + 'test_secret_key' => '' + ); + + $data = wp_parse_args($settings, $defaults); + return $key && isset($data[$key]) ? $data[$key] : $data; + } + + public static function getKeys($key = null) + { + $settings = self::getSettings(); + + if ($settings['payment_mode'] == 'test') { + $data = array( + 'secret' => $settings['test_secret_key'], + 'public' => $settings['test_pub_key'] + ); + } else { + $data = array( + 'secret' => $settings['live_secret_key'], + 'public' =>$settings['live_pub_key'] + ); + } + + return $key && isset($data[$key]) ? $data[$key] : $data; + + } + + + +} \ No newline at end of file diff --git a/includes/Builder/Render.php b/includes/Builder/Render.php index 23e2cf0..92249ec 100644 --- a/includes/Builder/Render.php +++ b/includes/Builder/Render.php @@ -206,7 +206,7 @@ public static function renderInputElements($template = []) -
+
@@ -230,8 +230,8 @@ public static function renderInputElements($template = []) to="360 20 20" dur="0.5s" repeatCount="indefinite"/>
- + +
diff --git a/src/js/Components/Stripe.vue b/src/js/Components/Stripe.vue index 7b5021e..aa19043 100644 --- a/src/js/Components/Stripe.vue +++ b/src/js/Components/Stripe.vue @@ -1,15 +1,12 @@