Skip to content

refundStarPayment

Returns: TrueOfficial docs ↗

Refunds a successful payment in Telegram Stars. Returns True on success.

Parameters

user_idIntegerRequired
Identifier of the user whose payment will be refunded
telegram_payment_charge_idStringRequired
Telegram payment identifier

Returns

On success, True is returned.

GramIO Usage

Refund a payment when you receive the successful_payment update and store the charge ID for later:

ts
// Store charge IDs mapped by user for later refund
const 
paymentStore
= new
Map
<number, string>();
bot
.
on
("message", (
ctx
) => {
const
payment
=
ctx
.
successfulPayment
;
if (!
payment
) return;
// Save the charge ID so we can refund later if needed
paymentStore
.
set
(
ctx
.
from
!.
id
,
payment
.
telegramPaymentChargeId
);
ctx
.
send
("Payment received! Thank you.");
});

Issue a refund by command when a user requests it:

ts
bot
.
command
("refund", async (
ctx
) => {
const
userId
=
ctx
.
from
!.
id
;
const
chargeId
=
paymentStore
.
get
(
userId
);
if (!
chargeId
) {
return
ctx
.
send
("No recent payment found for your account.");
} const
success
= await
bot
.
api
.
refundStarPayment
({
user_id
:
userId
,
telegram_payment_charge_id
:
chargeId
,
}); if (
success
) {
paymentStore
.
delete
(
userId
);
await
ctx
.
send
("Your payment has been refunded.");
} });

Refund directly inside a pre_checkout_query handler when your stock validation fails:

ts
bot
.
on
("pre_checkout_query", async (
ctx
) => {
const
isAvailable
= false; // replace with real stock check
if (!
isAvailable
) {
// Decline the checkout — Telegram will not charge the user await
ctx
.
answer
({
ok
: false,
error_message
: "Item is out of stock. Please try again later.",
}); return; } await
ctx
.
answer
({
ok
: true });
});

Errors

CodeErrorCause
400Bad Request: user not foundThe user_id does not correspond to a known Telegram user.
400Bad Request: CHARGE_NOT_FOUNDThe telegram_payment_charge_id is invalid or does not match a payment made to this bot.
400Bad Request: CHARGE_ALREADY_REFUNDEDThe payment with this charge ID has already been refunded. Each charge can only be refunded once.
403Forbidden: bot was blocked by the userThe user has blocked the bot. The refund cannot be delivered as a notification.
429Too Many Requests: retry after NFlood control triggered. Wait N seconds before retrying.

Tips & Gotchas

  • The telegram_payment_charge_id comes from SuccessfulPayment. After a user completes a Stars payment, Telegram sends a message with a successful_payment field. Read ctx.successfulPayment?.telegramPaymentChargeId and store it persistently — you will need it to issue refunds later.
  • Each charge ID can only be refunded once. Calling refundStarPayment a second time with the same telegram_payment_charge_id returns a 400 error. Check your database before issuing a refund to avoid double-refund attempts.
  • Refunds cannot be issued from pre_checkout_query. At the pre-checkout stage the user has not yet been charged, so there is nothing to refund — simply answer with ok: false and an error message to decline the payment before it processes.
  • Stars refunds are immediate and unconditional. Unlike credit-card gateways, there is no partial refund: the full amount is always returned to the user's Stars balance. There is no time limit enforced by the API, but it is good practice to refund promptly.
  • Store charge IDs durably. In-memory maps are lost on bot restarts. Persist telegram_payment_charge_id in a database keyed by user_id and order/item ID so you can always look them up when a user requests a refund days later.

See Also