在Ruby on Rails中使用receipts gem为PDF收据添加支付信息二维码
在Receipts Gem生成的PDF中插入支付详情二维码
问题背景
使用Chris Oliver开发的receipts gem生成PDF收据,需要在页脚区域插入包含charge.partner.iban、charge.amount等支付详情的二维码。此前尝试用prawn-qrcode生成二维码后通过image_tag传入footer参数,但仅能显示文本,无法正常渲染二维码。
解决方案
Receipts gem底层基于Prawn实现PDF生成,因此可以利用Prawn的API直接操作PDF对象插入二维码,具体步骤如下:
1. 安装依赖
首先确保Gemfile中包含生成二维码所需的依赖:
gem 'rqrcode' # 生成二维码数据 gem 'prawn-qrcode' # 支持Prawn插入二维码
执行bundle install安装依赖。
2. 修改Charge模型的receipt方法
在receipt方法中生成包含支付详情的二维码,并通过Receipts提供的custom_content回调插入到PDF指定位置:
def receipt # 准备二维码包含的支付数据,用JSON格式便于扫码后解析 qr_payload = { iban: partner.iban, amount: amount, receipt_number: "123", # 替换为实际收据编号字段 paid_at: created_at.strftime("%Y-%m-%d") }.to_json # 生成二维码PNG qrcode = RQRCode::QRCode.new(qr_payload) qr_png = qrcode.as_png( size: 100, # 二维码尺寸 border_modules: 2, # 边框宽度 color: 'black', # 码点颜色 fill: 'white' # 背景色 ) Receipts::Invoice.new( # 保留原有配置参数 details: [ ["Receipt Number", "123"], ["Date paid", Date.today], ["Payment method", "ACH super long super long super long super long super long"] ], company: { name: "Example, LLC", address: "123 Fake Street\nNew York City, NY 10012", email: "support@example.com", logo: File.expand_path("./app/assets/images/logo.png") }, recipient: [ partner.name, partner.address, "City, State Zipcode", nil, "customer@example.org" ], line_items: [ ["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"], ["Subscription", "$19.00", "1", "$19.00"], [nil, nil, "Subtotal", "$19.00"], [nil, nil, "Tax", "$1.12"], [nil, nil, "Total", "$20.12"], [nil, nil, "<b>Amount paid</b>", "$20.12"], [nil, nil, "Refunded on #{Date.today}", "$5.00"] ], footer: "Thanks for your business. Please contact us if you have any questions.", # 自定义内容回调:插入二维码到页脚右侧 custom_content: lambda { |pdf| # 坐标说明:x轴为PDF右边界减去二维码宽度-边距,y轴为PDF底边界加边距 pdf.image StringIO.new(qr_png.to_s), at: [pdf.bounds.right - 120, pdf.bounds.bottom + 20], width: 100 } ) end
3. 可选方案:在控制器中修改PDF
如果custom_content回调无法生效,也可以在send_pdf方法中直接操作Prawn对象:
private def send_pdf invoice = @charge.receipt pdf = invoice.render_pdf # 获取Prawn实例而非直接渲染字符串 # 生成二维码 qr_payload = { iban: @charge.partner.iban, amount: @charge.amount, receipt_number: "123", paid_at: @charge.created_at.strftime("%Y-%m-%d") }.to_json qrcode = RQRCode::QRCode.new(qr_payload) qr_png = qrcode.as_png(size: 100, border_modules: 2) # 插入二维码到页脚位置 pdf.image StringIO.new(qr_png.to_s), at: [pdf.bounds.right - 120, pdf.bounds.bottom + 20], width: 100 # 发送最终PDF send_data pdf.render, filename: "#{@charge.created_at.strftime("%Y-%m-%d")}-gorails-receipt.pdf", type: "application/pdf", disposition: :inline end
注意事项
- 二维码数据格式可根据需求调整:除了JSON,也可以用纯文本格式(如
IBAN: #{partner.iban} | Amount: #{amount}) - 坐标调整:
at: [x, y]参数需根据PDF实际尺寸微调,避免覆盖页脚文本或超出页面范围 - Logo路径问题:如果
File.expand_path找不到logo文件,可在模型中引入ActionView::Helpers::AssetUrlHelper后使用asset_path("logo.png")
内容的提问来源于stack exchange,提问作者Alexander V
相关产品推荐
相关产品推荐

