Cliente comprou, você quer devolver um cupom único de 10% pra ele voltar, e cadastrar um por um no admin não escala. Dá pra criar cupom no WooCommerce por código com a classe WC_Coupon, disparado no hook de pedido concluído. São umas quinze linhas.
A função no functions.php do tema filho
add_action('woocommerce_order_status_completed', 'rt_cupom_pos_compra');
function rt_cupom_pos_compra($order_id) {
$order = wc_get_order($order_id);
if (!$order || $order->get_meta('_rt_cupom')) {
return;
}
$codigo = 'volta' . strtolower(wp_generate_password(6, false, false));
$cupom = new WC_Coupon();
$cupom->set_code($codigo);
$cupom->set_discount_type('percent');
$cupom->set_amount(10);
$cupom->set_date_expires(strtotime('+30 days'));
$cupom->set_usage_limit(1);
$cupom->set_individual_use(true);
$cupom->set_email_restrictions([$order->get_billing_email()]);
$cupom->save();
$order->update_meta_data('_rt_cupom', $codigo);
$order->save();
}
Cupom continua sendo post do tipo shop_coupon (o HPOS mudou os pedidos, não os cupons), então o save() já cria o registro e ele vale no carrinho na hora. Guardo o código como meta do pedido pra não gerar dois se o status voltar pra processando e cair em concluído de novo, o que acontece mais do que você imagina.
Três pegadinhas
O código sempre vira minúsculo: o WooCommerce pendura wc_strtolower no filtro woocommerce_coupon_code. Se você gerar em maiúsculas e depois comparar com a string original, vai achar que o cupom sumiu. Já mando minúsculo e paro de sofrer.
A validade é comparada por timestamp cru, no estilo time() maior que a data de expiração. Quando o valor tem só a data, como acontece quando você cadastra pelo admin, o cupom morre à meia-noite que abre aquele dia e recusa durante o dia inteiro. Mandando o retorno de strtotime você fica com hora cheia e evita a reclamação.
E set_email_restrictions trava no e-mail de faturamento. Se o cliente comprar de novo com outro e-mail, o cupom recusa com mensagem genérica e ele te xinga no WhatsApp. Em loja com muito pedido de convidado, prefiro só usage_limit 1 e mando o código por e-mail.
Antes de subir, faça um pedido de um real, marque como concluído e confira em Marketing, Cupons se validade e limite gravaram como você esperava.