first commit

This commit is contained in:
Roman Pyrih
2025-08-26 10:50:15 +02:00
commit 97352dcdc9
6905 changed files with 2717203 additions and 0 deletions

View File

@@ -0,0 +1,191 @@
<?php
/**
* Class for the Stripe API.
*
* @link https://docs.stripe.com/api
*/
class WPCF7_Stripe_API {
const api_version = '2022-11-15';
const partner_id = 'pp_partner_HHbvqLh1AaO7Am';
const app_name = 'WordPress Contact Form 7';
const app_url = 'https://contactform7.com/stripe-integration/';
private $secret;
/**
* Constructor.
*
* @param string $secret Secret key.
*/
public function __construct( $secret ) {
$this->secret = $secret;
}
/**
* Sends a debug information for a remote request to the PHP error log.
*
* @param string $url URL to retrieve.
* @param array $request Request arguments.
* @param array|WP_Error $response The response or WP_Error on failure.
*/
private function log( $url, $request, $response ) {
wpcf7_log_remote_request( $url, $request, $response );
}
/**
* Returns default set of HTTP request headers used for Stripe API.
*
* @link https://docs.stripe.com/building-plugins#setappinfo
*
* @return array An associative array of headers.
*/
private function default_headers() {
$app_info = array(
'name' => self::app_name,
'partner_id' => self::partner_id,
'url' => self::app_url,
'version' => WPCF7_VERSION,
);
$ua = array(
'lang' => 'php',
'lang_version' => PHP_VERSION,
'application' => $app_info,
);
$headers = array(
'Authorization' => sprintf( 'Bearer %s', $this->secret ),
'Stripe-Version' => self::api_version,
'X-Stripe-Client-User-Agent' => wp_json_encode( $ua ),
'User-Agent' => sprintf(
'%1$s/%2$s (%3$s)',
self::app_name,
WPCF7_VERSION,
self::app_url
),
);
return $headers;
}
/**
* Creates a Payment Intent.
*
* @link https://docs.stripe.com/api/payment_intents/create
*
* @param string|array $args Optional. Arguments to control behavior.
* @return array|bool An associative array if 200 OK, false otherwise.
*/
public function create_payment_intent( $args = '' ) {
$args = wp_parse_args( $args, array(
'amount' => 0,
'currency' => '',
'receipt_email' => '',
) );
if ( ! is_email( $args['receipt_email'] ) ) {
unset( $args['receipt_email'] );
}
$endpoint = 'https://api.stripe.com/v1/payment_intents';
$request = array(
'headers' => $this->default_headers(),
'body' => $args,
);
$response = wp_remote_post( sanitize_url( $endpoint ), $request );
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
if ( WP_DEBUG ) {
$this->log( $endpoint, $request, $response );
}
return false;
}
$response_body = wp_remote_retrieve_body( $response );
$response_body = json_decode( $response_body, true );
return $response_body;
}
/**
* Retrieves a Payment Intent.
*
* @link https://docs.stripe.com/api/payment_intents/retrieve
*
* @param string $id Payment Intent identifier.
* @return array|bool An associative array if 200 OK, false otherwise.
*/
public function retrieve_payment_intent( $id ) {
$endpoint = sprintf(
'https://api.stripe.com/v1/payment_intents/%s',
urlencode( $id )
);
$request = array(
'headers' => $this->default_headers(),
);
$response = wp_remote_get( sanitize_url( $endpoint ), $request );
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
if ( WP_DEBUG ) {
$this->log( $endpoint, $request, $response );
}
return false;
}
$response_body = wp_remote_retrieve_body( $response );
$response_body = json_decode( $response_body, true );
return $response_body;
}
/**
* Updates a Payment Intent.
*
* @link https://docs.stripe.com/api/payment_intents/update
*
* @param string $id Payment Intent identifier.
* @param array $parameters Parameters.
* @return array|bool An associative array if 200 OK, false otherwise.
*/
public function update_payment_intent( $id, $parameters ) {
$endpoint = sprintf(
'https://api.stripe.com/v1/payment_intents/%s',
urlencode( $id )
);
$request = array(
'headers' => $this->default_headers(),
'body' => wp_parse_args( $parameters, array() ),
);
$response = wp_remote_post( sanitize_url( $endpoint ), $request );
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
if ( WP_DEBUG ) {
$this->log( $endpoint, $request, $response );
}
return false;
}
$response_body = wp_remote_retrieve_body( $response );
$response_body = json_decode( $response_body, true );
return $response_body;
}
}

View File

@@ -0,0 +1,6 @@
<?php
return array(
'dependencies' => array(),
'version' => WPCF7_VERSION,
);

View File

@@ -0,0 +1 @@
document.addEventListener("DOMContentLoaded",(e=>{const t=()=>{const e=document.querySelectorAll("form.wpcf7-form .wpcf7-stripe");for(let t=0;t<e.length;t++){let r=e[t];r.querySelector("button").disabled=!0;let i=document.createElement("span");i.setAttribute("class","wpcf7-not-valid-tip"),i.insertAdjacentText("beforeend","This form includes a payment widget that requires a modern browser to work."),r.appendChild(i)}};if(void 0===window.wpcf7_stripe)return console.error("window.wpcf7_stripe is not defined."),void t();if("function"!=typeof window.Stripe)return console.error("window.Stripe is not defined."),void t();if("function"!=typeof wpcf7.submit)return console.error("wpcf7.submit is not defined."),void t();const r=Stripe(wpcf7_stripe.publishable_key),i=r.elements();document.addEventListener("wpcf7submit",(e=>{const t=e.detail.unitTag,s=`${t}-ve-stripe-card-element`,n=document.querySelector(`#${t} form`),o=n.closest(".wpcf7").querySelector(".screen-reader-response"),d=n.querySelector(".wpcf7-stripe .wpcf7-form-control-wrap"),c=n.querySelector(".wpcf7-stripe button.first"),a=n.querySelector(".wpcf7-stripe button.second"),l=n.querySelector('[name="_wpcf7_stripe_payment_intent"]');if(!l)return;l.setAttribute("value","");const u=e=>{const t=o.querySelector("ul"),r=t.querySelector(`li#${s}`);r&&r.remove();const i=document.createElement("li");i.setAttribute("id",s),i.insertAdjacentText("beforeend",e.message),t.appendChild(i)},p=e=>{const t=d.querySelector(".wpcf7-form-control");t.classList.add("wpcf7-not-valid"),t.setAttribute("aria-describedby",s);const r=document.createElement("span");r.setAttribute("class","wpcf7-not-valid-tip"),r.setAttribute("aria-hidden","true"),r.insertAdjacentText("beforeend",e.message),d.appendChild(r),d.querySelectorAll("[aria-invalid]").forEach((e=>{e.setAttribute("aria-invalid","true")})),t.closest(".use-floating-validation-tip")&&(t.addEventListener("focus",(e=>{r.setAttribute("style","display: none")})),r.addEventListener("mouseover",(e=>{r.setAttribute("style","display: none")})))},f=()=>{o.querySelectorAll(`ul li#${s}`).forEach((e=>{e.remove()})),d.querySelectorAll(".wpcf7-not-valid-tip").forEach((e=>{e.remove()})),d.querySelectorAll("[aria-invalid]").forEach((e=>{e.setAttribute("aria-invalid","false")})),d.querySelectorAll(".wpcf7-form-control").forEach((e=>{e.removeAttribute("aria-describedby"),e.classList.remove("wpcf7-not-valid")}))};if("payment_required"===e.detail.status){const s=e.detail.apiResponse.stripe.payment_intent;s.id&&l.setAttribute("value",s.id);const o=i.getElement("card")||i.create("card");o.mount(`#${t} .wpcf7-stripe .card-element`),o.clear(),d.classList.remove("hidden"),c.classList.add("hidden"),a.classList.remove("hidden"),a.disabled=!0,o.addEventListener("change",(e=>{if(f(),e.error){const t={message:e.error.message};u(t),p(t),a.disabled=!0}else a.disabled=!1})),a.addEventListener("click",(e=>{f(),a.disabled=!0,n.classList.add("submitting"),wpcf7.blocked||r.confirmCardPayment(s.client_secret,{payment_method:{card:o}}).then((e=>{if(e.error){e.error.decline_code&&["fraudulent","lost_card","merchant_blacklist","pickup_card","restricted_card","security_violation","service_not_allowed","stolen_card","transaction_not_allowed"].includes(e.error.decline_code)&&(wpcf7.blocked=!0),n.classList.remove("submitting");const t={message:e.error.message};u(t),p(t)}else"succeeded"===e.paymentIntent.status&&wpcf7.submit(n)}))}))}else d.classList.add("hidden"),c.classList.remove("hidden"),a.classList.add("hidden"),["mail_sent","mail_failed"].includes(e.detail.status)&&(c.disabled=!0)}))}));

View File

@@ -0,0 +1,300 @@
<?php
if ( ! class_exists( 'WPCF7_Service' ) ) {
return;
}
class WPCF7_Stripe extends WPCF7_Service {
private static $instance;
private $api_keys;
public static function get_instance() {
if ( empty( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$option = WPCF7::get_option( 'stripe' );
if (
isset( $option['api_keys']['publishable'] ) and
isset( $option['api_keys']['secret'] )
) {
$this->api_keys = array(
'publishable' => $option['api_keys']['publishable'],
'secret' => $option['api_keys']['secret'],
);
}
}
public function get_title() {
return __( 'Stripe', 'contact-form-7' );
}
public function is_active() {
return (bool) $this->get_api_keys();
}
public function api() {
if ( $this->is_active() ) {
$api = new WPCF7_Stripe_API( $this->api_keys['secret'] );
return $api;
}
}
public function get_api_keys() {
return $this->api_keys;
}
public function get_categories() {
return array( 'payments' );
}
public function icon() {
}
public function link() {
echo wp_kses_data( wpcf7_link(
'https://stripe.com/',
'stripe.com'
) );
}
protected function menu_page_url( $args = '' ) {
$args = wp_parse_args( $args, array() );
$url = menu_page_url( 'wpcf7-integration', false );
$url = add_query_arg( array( 'service' => 'stripe' ), $url );
if ( ! empty( $args ) ) {
$url = add_query_arg( $args, $url );
}
return $url;
}
protected function save_data() {
WPCF7::update_option( 'stripe', array(
'api_keys' => $this->api_keys,
) );
}
protected function reset_data() {
$this->api_keys = null;
$this->save_data();
}
public function load( $action = '' ) {
if (
'setup' === $action and
'POST' === wpcf7_superglobal_server( 'REQUEST_METHOD' )
) {
check_admin_referer( 'wpcf7-stripe-setup' );
if ( ! empty( $_POST['reset'] ) ) {
$this->reset_data();
$redirect_to = $this->menu_page_url( 'action=setup' );
} else {
$publishable = wpcf7_superglobal_post( 'publishable' );
$secret = wpcf7_superglobal_post( 'secret' );
if ( $publishable and $secret ) {
$this->api_keys = array(
'publishable' => $publishable,
'secret' => $secret,
);
$this->save_data();
$redirect_to = $this->menu_page_url( array(
'message' => 'success',
) );
} else {
$redirect_to = $this->menu_page_url( array(
'action' => 'setup',
'message' => 'invalid',
) );
}
}
wp_safe_redirect( $redirect_to );
exit();
}
}
public function admin_notice( $message = '' ) {
if ( 'invalid' === $message ) {
wp_admin_notice(
__( '<strong>Error:</strong> Invalid key values.', 'contact-form-7' ),
array( 'type' => 'error' )
);
}
if ( 'success' === $message ) {
wp_admin_notice(
__( 'Settings saved.', 'contact-form-7' ),
array( 'type' => 'success' )
);
}
}
public function display( $action = '' ) {
$formatter = new WPCF7_HTMLFormatter( array(
'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array(
'form' => array(
'action' => true,
'method' => true,
),
) ),
) );
$formatter->append_start_tag( 'p' );
$formatter->append_preformatted(
esc_html( __( 'Stripe is a simple and powerful way to accept payments online. Stripe has no setup fees, no monthly fees, and no hidden costs. Millions of businesses rely on Stripe&#8217;s software tools to accept payments securely and expand globally.', 'contact-form-7' ) )
);
$formatter->end_tag( 'p' );
$formatter->append_start_tag( 'p' );
$formatter->append_start_tag( 'strong' );
$formatter->append_preformatted(
wpcf7_link(
__( 'https://contactform7.com/stripe-integration/', 'contact-form-7' ),
__( 'Stripe integration', 'contact-form-7' )
)
);
$formatter->end_tag( 'p' );
if ( $this->is_active() ) {
$formatter->append_start_tag( 'p', array(
'class' => 'dashicons-before dashicons-yes',
) );
$formatter->append_preformatted(
esc_html( __( 'Stripe is active on this site.', 'contact-form-7' ) )
);
$formatter->end_tag( 'p' );
}
if ( 'setup' === $action ) {
$formatter->call_user_func( function () {
$this->display_setup();
} );
} elseif ( is_ssl() or WP_DEBUG ) {
$formatter->append_start_tag( 'p' );
$formatter->append_start_tag( 'a', array(
'href' => esc_url( $this->menu_page_url( 'action=setup' ) ),
'class' => 'button',
) );
$formatter->append_preformatted(
esc_html( __( 'Setup integration', 'contact-form-7' ) )
);
$formatter->end_tag( 'p' );
} else {
$formatter->append_start_tag( 'p', array(
'class' => 'dashicons-before dashicons-warning',
) );
$formatter->append_preformatted(
esc_html( __( 'Stripe is not available on this site. It requires an HTTPS-enabled site.', 'contact-form-7' ) )
);
$formatter->end_tag( 'p' );
}
$formatter->print();
}
private function display_setup() {
$api_keys = $this->get_api_keys();
if ( $api_keys ) {
$publishable = $api_keys['publishable'];
$secret = $api_keys['secret'];
} else {
$publishable = '';
$secret = '';
}
?>
<form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>">
<?php wp_nonce_field( 'wpcf7-stripe-setup' ); ?>
<table class="form-table">
<tbody>
<tr>
<th scope="row"><label for="publishable"><?php echo esc_html( __( 'Publishable Key', 'contact-form-7' ) ); ?></label></th>
<td><?php
if ( $this->is_active() ) {
echo esc_html( $publishable );
echo sprintf(
'<input type="hidden" value="%s" id="publishable" name="publishable" />',
esc_attr( $publishable )
);
} else {
echo sprintf(
'<input type="text" aria-required="true" value="%s" id="publishable" name="publishable" class="regular-text code" />',
esc_attr( $publishable )
);
}
?></td>
</tr>
<tr>
<th scope="row"><label for="secret"><?php echo esc_html( __( 'Secret Key', 'contact-form-7' ) ); ?></label></th>
<td><?php
if ( $this->is_active() ) {
echo esc_html( wpcf7_mask_password( $secret ) );
echo sprintf(
'<input type="hidden" value="%s" id="secret" name="secret" />',
esc_attr( $secret )
);
} else {
echo sprintf(
'<input type="text" aria-required="true" value="%s" id="secret" name="secret" class="regular-text code" />',
esc_attr( $secret )
);
}
?></td>
</tr>
</tbody>
</table>
<?php
if ( $this->is_active() ) {
submit_button(
_x( 'Remove Keys', 'API keys', 'contact-form-7' ),
'small', 'reset'
);
} else {
submit_button( __( 'Save Changes', 'contact-form-7' ) );
}
?>
</form>
<?php
}
}

View File

@@ -0,0 +1,406 @@
<?php
/**
* Stripe module main file
*
* @link https://contactform7.com/stripe-integration/
*/
wpcf7_include_module_file( 'stripe/service.php' );
wpcf7_include_module_file( 'stripe/api.php' );
add_action(
'wpcf7_init',
'wpcf7_stripe_register_service',
50, 0
);
/**
* Registers the Stripe service.
*/
function wpcf7_stripe_register_service() {
$integration = WPCF7_Integration::get_instance();
$integration->add_service( 'stripe',
WPCF7_Stripe::get_instance()
);
}
add_action(
'wpcf7_enqueue_scripts',
'wpcf7_stripe_enqueue_scripts',
10, 0
);
/**
* Enqueues scripts and styles for the Stripe module.
*/
function wpcf7_stripe_enqueue_scripts() {
$service = WPCF7_Stripe::get_instance();
if ( ! $service->is_active() ) {
return;
}
wp_enqueue_style( 'wpcf7-stripe',
wpcf7_plugin_url( 'modules/stripe/style.css' ),
array(), WPCF7_VERSION, 'all'
);
wp_register_script(
'stripe',
'https://js.stripe.com/v3/',
array(),
null,
array( 'in_footer' => true )
);
$assets = include wpcf7_plugin_path( 'modules/stripe/index.asset.php' );
$assets = wp_parse_args( $assets, array(
'dependencies' => array(),
'version' => WPCF7_VERSION,
) );
wp_enqueue_script(
'wpcf7-stripe',
wpcf7_plugin_url( 'modules/stripe/index.js' ),
array_merge(
$assets['dependencies'],
array(
'wp-polyfill',
'contact-form-7',
'stripe',
)
),
$assets['version'],
array( 'in_footer' => true )
);
$api_keys = $service->get_api_keys();
if ( $api_keys['publishable'] ) {
wp_add_inline_script( 'wpcf7-stripe',
sprintf(
'var wpcf7_stripe = %s;',
wp_json_encode( array(
'publishable_key' => $api_keys['publishable'],
), JSON_PRETTY_PRINT )
),
'before'
);
}
}
add_filter(
'wpcf7_skip_spam_check',
'wpcf7_stripe_skip_spam_check',
10, 2
);
/**
* Skips the spam check if it is not necessary.
*
* @return bool True if the spam check is not necessary.
*/
function wpcf7_stripe_skip_spam_check( $skip_spam_check, $submission ) {
$service = WPCF7_Stripe::get_instance();
if ( ! $service->is_active() ) {
return $skip_spam_check;
}
$pi_id = (string) wpcf7_superglobal_post( '_wpcf7_stripe_payment_intent' );
if ( $pi_id ) {
$payment_intent = $service->api()->retrieve_payment_intent( $pi_id );
if (
isset( $payment_intent['metadata']['wpcf7_submission_timestamp'] )
) {
// This PI has already been used. Ignore.
return $skip_spam_check;
}
if (
isset( $payment_intent['status'] ) and
'succeeded' === $payment_intent['status']
) {
$submission->push( 'payment_intent', $pi_id );
$service->api()->update_payment_intent( $pi_id, array(
'metadata' => array_merge( $payment_intent['metadata'], array(
'wpcf7_submission_timestamp' => $submission->get_meta( 'timestamp' ),
) ),
) );
}
}
if (
! empty( $submission->pull( 'payment_intent' ) ) and
$submission->verify_posted_data_hash()
) {
$skip_spam_check = true;
}
return $skip_spam_check;
}
add_filter(
'wpcf7_spam',
'wpcf7_stripe_verify_payment_intent',
6, 2
);
/**
* Verifies submitted Stripe Payment Intent ID.
*/
function wpcf7_stripe_verify_payment_intent( $spam, $submission ) {
$service = WPCF7_Stripe::get_instance();
if ( ! $service->is_active() ) {
return $spam;
}
$pi_id = (string) wpcf7_superglobal_post( '_wpcf7_stripe_payment_intent' );
if ( $pi_id ) {
$payment_intent = $service->api()->retrieve_payment_intent( $pi_id );
if (
! $payment_intent or
isset( $payment_intent['metadata']['wpcf7_submission_timestamp'] )
) {
$spam = true;
$submission->add_spam_log( array(
'agent' => 'stripe',
'reason' => __(
'Invalid Stripe Payment Intent ID detected.',
'contact-form-7'
),
) );
}
}
return $spam;
}
add_action(
'wpcf7_before_send_mail',
'wpcf7_stripe_before_send_mail',
10, 3
);
/**
* Creates Stripe's Payment Intent.
*/
function wpcf7_stripe_before_send_mail( $contact_form, &$abort, $submission ) {
$service = WPCF7_Stripe::get_instance();
if ( ! $service->is_active() ) {
return;
}
$tags = $contact_form->scan_form_tags( array( 'type' => 'stripe' ) );
if ( ! $tags ) {
return;
}
if ( ! empty( $submission->pull( 'payment_intent' ) ) ) {
return;
}
$tag = $tags[0];
$amount = $tag->get_option( 'amount', 'int', true );
$currency = $tag->get_option( 'currency', '[a-zA-Z]{3}', true );
$payment_intent_params = apply_filters(
'wpcf7_stripe_payment_intent_parameters',
array(
'amount' => $amount ? absint( $amount ) : null,
'currency' => $currency ? strtolower( $currency ) : null,
'receipt_email' => $submission->get_posted_data( 'your-email' ),
)
);
$payment_intent = $service->api()->create_payment_intent(
$payment_intent_params
);
if ( $payment_intent ) {
$submission->add_result_props( array(
'stripe' => array(
'payment_intent' => array(
'id' => $payment_intent['id'],
'client_secret' => $payment_intent['client_secret'],
),
),
) );
$submission->set_status( 'payment_required' );
$submission->set_response(
__( 'Payment is required. Please pay by credit card.', 'contact-form-7' )
);
}
$abort = true;
}
/**
* Returns payment link URL.
*
* @param string $pi_id Payment Intent ID.
* @return string The URL.
*/
function wpcf7_stripe_get_payment_link( $pi_id ) {
return sprintf(
'https://dashboard.stripe.com/payments/%s',
urlencode( $pi_id )
);
}
add_filter(
'wpcf7_special_mail_tags',
'wpcf7_stripe_smt',
10, 4
);
/**
* Registers the [_stripe_payment_link] special mail-tag.
*/
function wpcf7_stripe_smt( $output, $tag_name, $html, $mail_tag = null ) {
if ( '_stripe_payment_link' === $tag_name ) {
$submission = WPCF7_Submission::get_instance();
$pi_id = $submission->pull( 'payment_intent' );
if ( ! empty( $pi_id ) ) {
$output = wpcf7_stripe_get_payment_link( $pi_id );
}
}
return $output;
}
add_filter(
'wpcf7_flamingo_inbound_message_parameters',
'wpcf7_stripe_add_flamingo_inbound_message_params',
10, 1
);
/**
* Adds Stripe-related meta data to Flamingo Inbound Message parameters.
*/
function wpcf7_stripe_add_flamingo_inbound_message_params( $args ) {
$submission = WPCF7_Submission::get_instance();
$pi_id = $submission->pull( 'payment_intent' );
if ( empty( $pi_id ) ) {
return $args;
}
$pi_link = wpcf7_stripe_get_payment_link( $pi_id );
$meta = (array) $args['meta'];
$meta['stripe_payment_link'] = $pi_link;
$args['meta'] = $meta;
return $args;
}
add_action(
'wpcf7_init',
'wpcf7_add_form_tag_stripe',
10, 0
);
/**
* Registers the stripe form-tag handler.
*/
function wpcf7_add_form_tag_stripe() {
wpcf7_add_form_tag(
'stripe',
'wpcf7_stripe_form_tag_handler',
array(
'display-block' => true,
'singular' => true,
)
);
}
/**
* Defines the stripe form-tag handler.
*
* @return string HTML content that replaces a stripe form-tag.
*/
function wpcf7_stripe_form_tag_handler( $tag ) {
$card_element = sprintf(
'<div %s></div>',
wpcf7_format_atts( array(
'class' => 'card-element wpcf7-form-control',
'aria-invalid' => 'false',
) )
);
$card_element = sprintf(
'<div class="wpcf7-form-control-wrap hidden">%s</div>',
$card_element
);
$button_1_label = __( 'Proceed to checkout', 'contact-form-7' );
if ( isset( $tag->values[0] ) ) {
$button_1_label = trim( $tag->values[0] );
}
$button_1 = sprintf(
'<button %1$s>%2$s</button>',
wpcf7_format_atts( array(
'type' => 'submit',
'class' => 'first',
) ),
esc_html( $button_1_label )
);
$button_2_label = __( 'Complete payment', 'contact-form-7' );
if ( isset( $tag->values[1] ) ) {
$button_2_label = trim( $tag->values[1] );
}
$button_2 = sprintf(
'<button %1$s>%2$s</button>',
wpcf7_format_atts( array(
'type' => 'button',
'class' => 'second hidden',
) ),
esc_html( $button_2_label )
);
$buttons = sprintf(
'<span class="buttons has-spinner">%1$s %2$s</span>',
$button_1, $button_2
);
return sprintf(
'<div class="wpcf7-stripe">%1$s %2$s %3$s</div>',
$card_element,
$buttons,
'<input type="hidden" name="_wpcf7_stripe_payment_intent" value="" />'
);
}

View File

@@ -0,0 +1,18 @@
.wpcf7 .wpcf7-stripe .wpcf7-form-control-wrap {
margin: .6em 0;
}
.wpcf7 .wpcf7-stripe .wpcf7-form-control {
display: block;
background: #f6f7f7;
padding: 12px 12px;
border: 1px solid #787c82;
}
.wpcf7 .wpcf7-stripe button:disabled {
cursor: not-allowed;
}
.wpcf7 .wpcf7-stripe .hidden {
display: none;
}