Restructure skill numbering: SEO 11-30, GTM 60-69, reserve 19-28 for future skills
Renumber 12 existing skills to new ranges: - SEO: 11→13, 12→18, 13→16, 14→17, 15→14, 16→15, 17→29, 18→30, 19→12 - GTM: 20→60, 21→61, 22→62 Update cross-references in gateway architect/builder skills, GTM guardian README, CLAUDE.md (skill tables + directory layout), and AGENTS.md (domain routing ranges). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
237
custom-skills/60-gtm-audit/code/docs/checkout_flow.md
Normal file
237
custom-skills/60-gtm-audit/code/docs/checkout_flow.md
Normal file
@@ -0,0 +1,237 @@
|
||||
# E-commerce Checkout Flow Reference
|
||||
|
||||
## Complete Checkout Event Sequence
|
||||
|
||||
```
|
||||
view_cart → begin_checkout → add_shipping_info → add_payment_info → purchase
|
||||
```
|
||||
|
||||
Each step must fire in order with consistent item data.
|
||||
|
||||
## Event Details
|
||||
|
||||
### 1. view_cart
|
||||
When user views cart page.
|
||||
|
||||
```javascript
|
||||
dataLayer.push({ ecommerce: null });
|
||||
dataLayer.push({
|
||||
event: "view_cart",
|
||||
ecommerce: {
|
||||
currency: "KRW",
|
||||
value: 125000,
|
||||
items: [{
|
||||
item_id: "SKU_001",
|
||||
item_name: "Blue T-Shirt",
|
||||
price: 45000,
|
||||
quantity: 2,
|
||||
item_brand: "Brand",
|
||||
item_category: "Apparel"
|
||||
}, {
|
||||
item_id: "SKU_002",
|
||||
item_name: "Black Jeans",
|
||||
price: 35000,
|
||||
quantity: 1
|
||||
}]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 2. begin_checkout
|
||||
When user initiates checkout process.
|
||||
|
||||
```javascript
|
||||
dataLayer.push({ ecommerce: null });
|
||||
dataLayer.push({
|
||||
event: "begin_checkout",
|
||||
ecommerce: {
|
||||
currency: "KRW",
|
||||
value: 125000,
|
||||
coupon: "SUMMER10",
|
||||
items: [/* same items as view_cart */]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 3. add_shipping_info
|
||||
When user completes shipping step.
|
||||
|
||||
```javascript
|
||||
dataLayer.push({ ecommerce: null });
|
||||
dataLayer.push({
|
||||
event: "add_shipping_info",
|
||||
ecommerce: {
|
||||
currency: "KRW",
|
||||
value: 125000,
|
||||
coupon: "SUMMER10",
|
||||
shipping_tier: "Express", // Required
|
||||
items: [/* same items */]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**shipping_tier values:**
|
||||
- "Standard" / "일반배송"
|
||||
- "Express" / "익일배송"
|
||||
- "Same Day" / "당일배송"
|
||||
- "Free" / "무료배송"
|
||||
- "Store Pickup" / "매장픽업"
|
||||
|
||||
### 4. add_payment_info
|
||||
When user enters payment details.
|
||||
|
||||
```javascript
|
||||
dataLayer.push({ ecommerce: null });
|
||||
dataLayer.push({
|
||||
event: "add_payment_info",
|
||||
ecommerce: {
|
||||
currency: "KRW",
|
||||
value: 125000,
|
||||
coupon: "SUMMER10",
|
||||
payment_type: "Credit Card", // Required
|
||||
items: [/* same items */]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**payment_type values:**
|
||||
- "Credit Card" / "신용카드"
|
||||
- "Debit Card" / "체크카드"
|
||||
- "Bank Transfer" / "계좌이체"
|
||||
- "Virtual Account" / "가상계좌"
|
||||
- "Mobile Payment" / "휴대폰결제"
|
||||
- "Kakao Pay" / "카카오페이"
|
||||
- "Naver Pay" / "네이버페이"
|
||||
- "Toss" / "토스"
|
||||
- "PayPal"
|
||||
|
||||
### 5. purchase
|
||||
When transaction completes successfully.
|
||||
|
||||
```javascript
|
||||
dataLayer.push({ ecommerce: null });
|
||||
dataLayer.push({
|
||||
event: "purchase",
|
||||
ecommerce: {
|
||||
transaction_id: "T_20250115_001234", // Required, unique
|
||||
value: 130500, // Required (total)
|
||||
tax: 11863,
|
||||
shipping: 5000,
|
||||
currency: "KRW", // Required
|
||||
coupon: "SUMMER10",
|
||||
items: [{
|
||||
item_id: "SKU_001",
|
||||
item_name: "Blue T-Shirt",
|
||||
affiliation: "Online Store",
|
||||
coupon: "SUMMER10",
|
||||
discount: 4500,
|
||||
price: 45000,
|
||||
quantity: 2
|
||||
}]
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Funnel Drop-off Analysis
|
||||
|
||||
### Tracking Drop-offs
|
||||
Monitor completion rate at each step:
|
||||
|
||||
| Step | Event | Drop-off Indicator |
|
||||
|------|-------|-------------------|
|
||||
| Cart | view_cart | User leaves cart page |
|
||||
| Checkout Start | begin_checkout | User doesn't proceed |
|
||||
| Shipping | add_shipping_info | Address form abandoned |
|
||||
| Payment | add_payment_info | Payment not completed |
|
||||
| Complete | purchase | Transaction failed |
|
||||
|
||||
### Implementing Drop-off Tracking
|
||||
|
||||
```javascript
|
||||
// Track checkout step viewed but not completed
|
||||
let checkoutStep = 0;
|
||||
|
||||
function trackCheckoutProgress(step) {
|
||||
if (step > checkoutStep) {
|
||||
checkoutStep = step;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (checkoutStep > 0 && checkoutStep < 5) {
|
||||
dataLayer.push({
|
||||
event: 'checkout_abandon',
|
||||
last_step: checkoutStep,
|
||||
step_name: ['cart', 'checkout', 'shipping', 'payment', 'complete'][checkoutStep - 1]
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Value Consistency Check
|
||||
|
||||
Ensure `value` matches across events:
|
||||
|
||||
```
|
||||
view_cart.value = sum(items.price * items.quantity)
|
||||
begin_checkout.value = view_cart.value
|
||||
add_shipping_info.value = begin_checkout.value
|
||||
add_payment_info.value = add_shipping_info.value
|
||||
purchase.value = add_payment_info.value + shipping + tax - discount
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Duplicate Purchase Events
|
||||
**Problem**: Same order tracked multiple times
|
||||
**Solution**:
|
||||
```javascript
|
||||
// Check if already tracked
|
||||
const txId = "T_12345";
|
||||
if (!sessionStorage.getItem('purchase_' + txId)) {
|
||||
dataLayer.push({ event: 'purchase', ... });
|
||||
sessionStorage.setItem('purchase_' + txId, 'true');
|
||||
}
|
||||
```
|
||||
|
||||
### Missing Items in Later Steps
|
||||
**Problem**: Items present in view_cart but missing in purchase
|
||||
**Solution**: Store cart data in session and reuse
|
||||
|
||||
### Inconsistent Currency
|
||||
**Problem**: Some events use USD, others KRW
|
||||
**Solution**: Standardize currency across all events
|
||||
|
||||
### Wrong Value Calculation
|
||||
**Problem**: purchase.value doesn't include tax/shipping
|
||||
**Solution**:
|
||||
```
|
||||
purchase.value = subtotal + tax + shipping - discount
|
||||
```
|
||||
|
||||
## Korean E-commerce Platforms
|
||||
|
||||
### Cafe24
|
||||
Custom dataLayer variable names - check documentation
|
||||
|
||||
### Shopify Korea
|
||||
Standard GA4 format with `Shopify.checkout` object
|
||||
|
||||
### WooCommerce
|
||||
Use official GA4 plugin or custom implementation
|
||||
|
||||
### Naver SmartStore
|
||||
Separate Naver Analytics implementation required
|
||||
|
||||
## Checkout Flow Checklist
|
||||
|
||||
- [ ] view_cart fires on cart page load
|
||||
- [ ] begin_checkout fires on checkout button click
|
||||
- [ ] add_shipping_info includes shipping_tier
|
||||
- [ ] add_payment_info includes payment_type
|
||||
- [ ] purchase has unique transaction_id
|
||||
- [ ] All events have consistent items array
|
||||
- [ ] Currency is consistent across all events
|
||||
- [ ] Value calculations are accurate
|
||||
- [ ] ecommerce object cleared before each push
|
||||
- [ ] Purchase event fires only once per order
|
||||
Reference in New Issue
Block a user