Implements Apple Pay and Google Pay wallet buttons via the Revolut Merchant Web SDK. Activates when building wallet payments, adding Apple Pay or Google Pay buttons, or when user mentions Apple Pay, Google Pay, wallet payments, or digital wallets.
How this skill is triggered — by the user, by Claude, or both
Slash command
/laravel-revolut-skill:revolut-apple-google-payThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Activate this skill when:
Activate this skill when:
Apple Pay: https://developer.revolut.com/docs/sdks/merchant-web-sdk/apple-pay Google Pay: https://developer.revolut.com/docs/sdks/merchant-web-sdk/google-pay
Revolut's SDK renders Apple Pay and Google Pay buttons when the customer's browser and device support them. The buttons only appear automatically — you do not render a fallback; show an alternative payment method instead.
use Lartisan\Revolut\Facades\Revolut;
Route::post('/wallet/order', function (Request $request) {
$order = Revolut::createOrder([
'amount' => $request->integer('amount'),
'currency' => 'GBP',
'description' => 'Wallet checkout',
'redirect_url' => route('checkout.success'),
'cancel_redirect_url' => route('checkout.cancel'),
]);
return response()->json(['public_id' => $order->public_id]);
});
<div id="apple-pay-btn"></div>
<script src="https://merchant.revolut.com/embed.js"></script>
<script>
async function mountApplePay() {
const res = await fetch('/wallet/order', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content,
},
body: JSON.stringify({ amount: 2999 }),
});
const { public_id } = await res.json();
RevolutCheckout(public_id, 'sandbox').applePay({
target: document.getElementById('apple-pay-btn'),
buttonStyle: 'black', // 'black' | 'white' | 'white-with-line'
buttonType: 'buy', // 'buy' | 'pay' | 'check-out' | 'book' | 'subscribe' | 'plain'
onSuccess() {
window.location.href = '/checkout/success';
},
onError(message) {
console.error('Apple Pay failed:', message);
},
});
}
mountApplePay();
</script>
<div id="google-pay-btn"></div>
<script src="https://merchant.revolut.com/embed.js"></script>
<script>
async function mountGooglePay() {
const res = await fetch('/wallet/order', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content,
},
body: JSON.stringify({ amount: 2999 }),
});
const { public_id } = await res.json();
RevolutCheckout(public_id, 'sandbox').googlePay({
target: document.getElementById('google-pay-btn'),
buttonColor: 'black', // 'black' | 'white'
buttonType: 'buy', // 'buy' | 'pay' | 'checkout' | 'book' | 'subscribe' | 'plain'
onSuccess() {
window.location.href = '/checkout/success';
},
onError(message) {
console.error('Google Pay failed:', message);
},
});
}
mountGooglePay();
</script>
The wallet buttons render asynchronously. Use canMakePayment() to check availability before deciding whether to show a fallback:
<div id="apple-pay-btn"></div>
<div id="google-pay-btn"></div>
<div id="standard-checkout" style="display:none">
<button id="pay-btn">Pay by card</button>
</div>
<script src="https://merchant.revolut.com/embed.js"></script>
<script>
async function mountWalletButtons() {
const { public_id } = await fetch('/wallet/order', { method: 'POST', ... })
.then(r => r.json());
const instance = RevolutCheckout(public_id, 'sandbox');
const callbacks = {
onSuccess: () => { window.location.href = '/success'; },
onError: (msg) => { alert(msg); },
};
// Check support before mounting — avoids showing empty placeholders
const [appleSupported, googleSupported] = await Promise.all([
instance.applePay({ target: document.getElementById('apple-pay-btn'), ...callbacks })
.canMakePayment().catch(() => false),
instance.googlePay({ target: document.getElementById('google-pay-btn'), ...callbacks })
.canMakePayment().catch(() => false),
]);
if (!appleSupported && !googleSupported) {
document.getElementById('standard-checkout').style.display = 'block';
}
}
mountWalletButtons();
</script>
Note: If
canMakePayment()is not available in the SDK version you are using, use theonImmediatePaymentMethodsReadycallback or observe DOM mutations on the target containers as a fallback detection strategy. AvoidsetTimeout— it is unreliable on slow connections.
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-associationRoute::get('/.well-known/apple-developer-merchantid-domain-association', function () {
return response()->file(storage_path('app/apple-pay-domain-association'))
->header('Content-Type', 'text/plain');
});
canMakePayment() rather than setTimeout to detect support'prod' environment before completing platform registration'sandbox' in RevolutCheckout(public_id, 'sandbox') — pass the environment from your backend (see revolut-integration skill)npx claudepluginhub lartisan/laravel-revolut-skill --plugin laravel-revolut-skillCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.