Skip to content

Instantly share code, notes, and snippets.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pay Here</title>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
</head>
<body class="font-sans">
<header class="bg-white shadow-sm">
@phawk
phawk / payhere_embed_sdk.html
Last active December 29, 2020 08:00
Payhere embed SDK example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Embed Test Site</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
.container {
margin: 4rem auto;
@phawk
phawk / graphql.js
Created August 23, 2019 17:01
Lambda Shopify graphql proxy endpoint
const https = require("https")
const fetch = require("isomorphic-fetch")
const Account = require("./models/account")
const authenticated = require("./lib/auth")
exports.handler = authenticated(async (event, context) => {
const { id: shopId, shopifyToken } = context.account
try {
const resp = await fetch(`https://${shopId}/admin/api/2019-07/graphql.json`, {
@phawk
phawk / authentication.js
Created August 23, 2019 16:53
Lambda HoC for authenticating requests with dynamoDB
const Account = require("../models/account")
module.exports = (handler) => async (event, context) => {
let auth = event.headers.authorization
auth = auth.replace(/^Basic\s/, "")
auth = Buffer.from(auth, 'base64').toString()
const [id, token] = auth.split(":")
const account = await Account.get({ id })
@phawk
phawk / getToken.js
Created August 23, 2019 16:19
Shopify exchange OAuth code for token and create user account
const crypto = require("crypto")
const querystring = require("querystring")
const fetch = require("isomorphic-fetch")
const Account = require("./models/account")
exports.handler = async (event, context) => {
const { shop, hmac, code, timestamp } = event.queryStringParameters
const apiKey = process.env.SHOPIFY_API_KEY
const apiSecret = process.env.SHOPIFY_API_SECRET
@phawk
phawk / install.js
Created August 23, 2019 16:17
Shopify install lambda
exports.handler = async (event, context) => {
const shop = event.queryStringParameters.shop
const redirectUri = event.queryStringParameters.redirect
const apiKey = process.env.SHOPIFY_API_KEY
const scopes="read_content,write_content,read_products,read_themes,write_themes"
if (shop) {
const installUrl = 'https://' + shop +
'/admin/oauth/authorize?client_id=' + apiKey +
'&scope=' + scopes +
@phawk
phawk / payhere_webhooks_controller.rb
Created February 20, 2019 16:03
Benmudge.com PayHere Webhooks integration
module Events
class PayhereWebhooksController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
def create
return head 401 unless valid_signature?
if payment_params[:status] == "success"
user = find_or_create_user
@phawk
phawk / payhere_embed_demo.html
Created February 17, 2019 17:41
PayHere embed
<button data-payhere-embed="https://payhere.co/altlabs/membership/pro-plan">Subscribe now</button>
<script src="https://payhere.co/embed/embed.js"></script>
@phawk
phawk / NSImage+QuickLook.swift
Created February 15, 2018 20:14
Swift macOS generate image previews of files on disk
import AppKit
import QuickLook
extension NSImage {
static func previewForFile(path fileURL: URL, ofSize size: CGSize, asIcon: Bool) -> NSImage? {
let dict = [
kQLThumbnailOptionIconModeKey: NSNumber(booleanLiteral: asIcon)
] as CFDictionary
@phawk
phawk / non-single-use.html.erb
Created December 4, 2017 22:06
Single use classes HTML bloat
<%= page_title("Account") %>
<%= render 'my_account/shared/header', current_section: "rewards" %>
<div class="container">
<div class="tab-content">
<div class="grid">
<div class="col-2-3">
<h3 class="heading">Bonus Points <span>2/8 bonus points earned</span></h3>
<p>Get even greater value from your rewards points by redeeming them against these special offers below. These offers are a one time only use and only unlock as and when you reach the Rewards Level required to do so.</p>