How to log charges on subscription using payment_link

Hi! I’d like to create subscription using Square payment link api. After this I’d like to log all charges on subscription and show them to the user, but I haven’t found a clear way on how to do this. This article How can I cancel subscription which was created by checkout api - #6 by supergodk mentions that subscription_id doesn’t sent in the response for createPaymentLink. In this case I have a lot of problems on how to match order, invoice, subscription together. Could you suggest me the correct way which allows to catch all successful and unsuccessful charges on subscription.
My current code using PHP SDK

function square_create_payment_link( $custom ): string|bool {
	global $current_user, $square, $square_env_config;

	$paymentLink = $square->checkout->paymentLinks->create(
		new CreatePaymentLinkRequest( [
			'idempotencyKey'  => uniqid(),
			'quickPay'        => new QuickPay( [
				'locationId' => $square_env_config['LOCATION_ID'],
				'name'       => 'Card protection',
				'priceMoney' => new Money( [
					'amount'   => 100,
					'currency' => Currency::Usd->value,
				] ),
			] ),
			'checkoutOptions' => new CheckoutOptions( [
				'subscriptionPlanId' => $square_env_config['SUBSCRIPTION_PLAN_VARIATION_DATA_ID'],
				"redirectUrl"        => get_pending_page()
			] ),
			'description'     => 'Billed monthly',
		] ),
	);

	if ( $paymentLink->getPaymentLink() ) {
		return $paymentLink->getPaymentLink()->getUrl();
	}

	return false;
}

add_action( 'rest_api_init', 'square_init_rest_endpoints' );

function square_init_rest_endpoints(): void {
	register_rest_route( 'payments/square', '/subscription-created', array(
		'methods'             => 'POST',
		'permission_callback' => '__return_true',
		'callback'            => 'square_subscription_created',
	) );

	register_rest_route( 'payments/square', '/subscription-updated', array(
		'methods'             => 'POST',
		'permission_callback' => '__return_true',
		'callback'            => 'square_subscription_updated',
	) );

	register_rest_route( 'payments/square', '/payment-updated', array(
		'methods'             => 'POST',
		'permission_callback' => '__return_true',
		'callback'            => 'square_payment_updated',
	) );
}

That’s correct, a subscription_id isn’t available till the customer checks out and the subscription is created. You have a couple of ways to get the subscription that’s created. You can get the customer_id from the payment and search the subscriptions with that or listen to webhook events and match the customer_id with a subscription.created webhook event. :slight_smile:

Users on my service can have multiple subscriptions. How can I be sure that I get the subscription I need. As I understand, I have to catch successful or unsuccessful payments, and possible cancellation of subscription, which are multiple instances

That’s correct, you’ll need to use webhooks to ensure that your getting the correct subscription matched with the customer. :slight_smile:

Suppose I’d like to catch successful or unsuccessful payments. I would use payment.updated webhook. I’d get id and status of payment, as well as the customer id, but how can I combine it with subscription, how to understand that this payment refer to a certain subscription.

The payment will have an order_id in it. The subscriptions uses invoices to bill subscriptions. If you also listen to invoice webhooks you can match order_id from the payment with the invoice.

Also each invoice_id will be added to an array in the subscription object that you can retrieve from the Subscriptions API. :slight_smile:

I’m using createPaymentLink to create subscription, I’ve also added a webhook to catch all invoice events, but it seems no webhooks for invoices triggered.

I can also attach only one image in one message :slightly_frowning_face:

Yes, that is expected in sandbox. The full flow isn’t currently available in sandbox at this time. They will trigger in production. We’re constantly working to improve our features based on feedback like this, so I’ll be sure to share your request to the API product team. :slight_smile: