182 lines
4.9 KiB
PHP

<?php
/**
* Webhooks.
*
* @package EDD_Stripe
* @since 2.7.0
*/
/**
* Listen for Stripe Webhooks.
*
* @since 1.5
*/
function edds_stripe_event_listener() {
if ( ! isset( $_GET['edd-listener'] ) || 'stripe' !== $_GET['edd-listener'] ) {
return;
}
try {
// Retrieve the request's body and parse it as JSON.
$body = @file_get_contents( 'php://input' );
$event = json_decode( $body );
if ( isset( $event->id ) ) {
$event = edds_api_request( 'Event', 'retrieve', $event->id );
} else {
throw new \Exception( esc_html__( 'Unable to find Event', 'easy-digital-downloads' ) );
}
// Handle events.
//
switch ( $event->type ) {
// Charge succeeded. Update EDD Payment address.
case 'charge.succeeded' :
$charge = $event->data->object;
$payment_id = edd_get_purchase_id_by_transaction_id( $charge->id );
$payment = new EDD_Payment( $payment_id );
if ( $payment && $payment->ID > 0 ) {
$payment->address = array(
'line1' => $charge->billing_details->address->line1,
'line2' => $charge->billing_details->address->line2,
'state' => $charge->billing_details->address->state,
'city' => $charge->billing_details->address->city,
'zip' => $charge->billing_details->address->postal_code,
'country' => $charge->billing_details->address->country,
);
$payment->save();
}
break;
// Charge refunded. Ensure EDD Payment status is correct.
case 'charge.refunded':
$charge = $event->data->object;
$payment_id = edd_get_purchase_id_by_transaction_id( $charge->id );
$payment = new EDD_Payment( $payment_id );
// This is an uncaptured PaymentIntent, not a true refund.
if ( ! $charge->captured ) {
return;
}
if ( $payment && $payment->ID > 0 ) {
// If this was completely refunded, set the status to refunded.
if ( $charge->refunded ) {
$payment->status = 'refunded';
$payment->save();
// Translators: The charge ID from Stripe that is being refunded.
$payment->add_note( sprintf( __( 'Charge %s has been fully refunded in Stripe.', 'easy-digital-downloads' ), $charge->id ) );
// If this was partially refunded, don't change the status.
} else {
// Translators: The charge ID from Stripe that is being partially refunded.
$payment->add_note( sprintf( __( 'Charge %s partially refunded in Stripe.', 'easy-digital-downloads' ), $charge->id ) );
}
}
break;
// Review started.
case 'review.opened' :
$is_live = ! edd_is_test_mode();
$review = $event->data->object;
// Make sure the modes match.
if ( $is_live !== $review->livemode ) {
return;
}
$charge = $review->charge;
// Get the charge from the PaymentIntent.
if ( ! $charge ) {
$payment_intent = $review->payment_intent;
if ( ! $payment_intent ) {
return;
}
$payment_intent = edds_api_request( 'PaymentIntent', 'retrieve', $payment_intent );
$charge = $payment_intent->charges->data[0]->id;
}
$payment_id = edd_get_purchase_id_by_transaction_id( $charge );
$payment = new EDD_Payment( $payment_id );
if ( $payment && $payment->ID > 0 ) {
$payment->add_note(
sprintf(
/* translators: %s Stripe Radar review opening reason. */
__( 'Stripe Radar review opened with a reason of %s.', 'easy-digital-downloads' ),
$review->reason
)
);
$payment->save();
do_action( 'edd_stripe_review_opened', $review, $payment_id );
}
break;
// Review closed.
case 'review.closed' :
$is_live = ! edd_is_test_mode();
$review = $event->data->object;
// Make sure the modes match
if ( $is_live !== $review->livemode ) {
return;
}
$charge = $review->charge;
// Get the charge from the PaymentIntent.
if ( ! $charge ) {
$payment_intent = $review->payment_intent;
if ( ! $payment_intent ) {
return;
}
$payment_intent = edds_api_request( 'PaymentIntent', 'retrieve', $payment_intent );
$charge = $payment_intent->charges->data[0]->id;
}
$payment_id = edd_get_purchase_id_by_transaction_id( $charge );
$payment = new EDD_Payment( $payment_id );
if ( $payment && $payment->ID > 0 ) {
$payment->add_note(
sprintf(
/* translators: %s Stripe Radar review closing reason. */
__( 'Stripe Radar review closed with a reason of %s.', 'easy-digital-downloads' ),
$review->reason
)
);
$payment->save();
do_action( 'edd_stripe_review_closed', $review, $payment_id );
}
break;
}
do_action( 'edds_stripe_event_' . $event->type, $event );
// Nothing failed, mark complete.
status_header( 200 );
die( esc_html( 'EDD Stripe: ' . $event->type ) );
// Fail, allow a retry.
} catch ( \Exception $e ) {
status_header( 500 );
die( '-2' );
}
}
add_action( 'init', 'edds_stripe_event_listener' );